Java多线程之锁

首先是synchronized 关键字

他可以用于声明方法,也可以用于申明代码块。我们看看三个例子:

public class SynchronizedDemo1 {
    
    public synchronized static void foo1() {
        
    }
    
    public synchronized static void foo2() {
        
    }
}
public class SynchronizedDemo2 {

    public synchronized void foo3() {

    }

    public synchronized void foo4() {

    }
}
public class SynchronizedDemo3 {

    public void foo5() {
        synchronized (this) {

        }

    }

    public void foo6() {
        synchronized (SynchronizedDemo3.class) {
            
        }
    }
}

第一个例子中,在不同线程中,两个方法的调用是互斥的,不仅是他们之间,任何两个不同线程的调用也互斥。

第二个例子中,在多线程环境中,调用同一个对象的foo3,foo4是互斥的,与例子1不同的是,这是针对同一个对象的互斥方法。

第三个例子中,synchronized (this)与synchronized 的成员方法是互斥的,和第二个例子类似。synchronized (SynchronizedDemo3.class)与synchronized 的静态方法是互斥的,和第一个例子类似。

synchronized 用于修饰代码块会更加的灵活,因为后面的参数可以是任意对象,还可以缩小加锁的范围,不用在整个方法上加锁。

 

ReentrantLock

下面是Lock接口:

public interface Lock {

    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    void unlock();

    Condition newCondition();
}

ReentrantLock实现了Lock接口,并提供了与synchronized相同的呼哧性和内存可见性,在获取ReentrantLock有着与进入同步代码块相同的内存语义,在释放ReentrantLock时候,同样有着与退出同步代码块相同的意义。ReentrantLock支持在Lock接口中定义的所有获取锁的模式,并且与synchronized相比,它在处理锁不可用的时候,灵活性更好。下面是ReentrantLock的常见使用形式,必须在finally块中释放锁

    Lock lock = new ReentrantLock();


    lock.lock();
        try {
            //更新对象状态
            //捕获异常,并在必要时进行处理
        }finally {
            lock.unlock();
        }

ReentrantLock相对于synchronized有更好的灵活性已经更多功能,比如:

   1.lock.tryLock()可以返回是否获得锁,如果没有获得会立即返回false,如果获得则当前调用线程会获得锁,并理解返回true。

 2.构造ReentrantLock的时候可以传入一个boolean值,那就是描述锁是否公平。公平锁的好处是等待锁的线程不会饿死,但是整体效率要低一些;非公平锁的好处是整体效率相对高一些,但是有些线程可能会饿死,或者说很早就在等待但是要等很久才等到。原因是公平锁是严格按照请求锁的顺序来排队的,而非公平可以是抢占的,如果某个时刻有个线程需要获得锁,而这时候刚好锁可用,那么这个线程就直接抢占,而这时候阻塞在等待队列上的线程则不会被唤醒。

此外ReentrantLock也提供了ReentrantReadWriteLock,从名字上看就可以看出是读写锁,主要用于读多写少的情况。这样的场景使用读写锁会比全部使用互斥锁性能高很多。

ReentrantReadWriteLock用法与ReentrantLock类似,差异是ReentrantReadWriteLock是通过readLock()和writeLock()两个方法获得相关的读锁和写锁。  

    原文作者:纵酒挥刀斩人头
    原文地址: https://www.cnblogs.com/hupengcool/p/3757313.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞