Java高并发程序设计(三)--重入锁和它的好搭档condition条件

重入锁是对synchronize的增强,可以代替synchronize。

重入锁使用java.util.concurrent.locks.ReentrantLock来实现。下面是一个简单的例子,相对于synchronize来说,重入锁更加细致,也更加灵活。

public class threadDemo implements Runnable{
    public static ReentrantLock lock=new ReentrantLock() ;
    public static int i=0;
    public static void main(String[] args) throws InterruptedException
    {
        threadDemo t=new threadDemo();
        Thread t1=new Thread(t);
        Thread t2=new Thread(t);
        t1.start();t1.join();
        t2.start();t2.join();
        System.out.println(i);
    }

    public void run() {
        for(int j=0;j<10000;j++)
        {
            lock.lock();
            try
            {
                i++;
            }
            finally
            {
                lock.unlock();
            }
        }
    }
}

之所以叫重入锁,是因为对同一线程来说,这种锁是可以反复进入的。

它还可以获得数次锁,如下所示

for(int j=0;j<10000;j++)
        {
            lock.lock();
            lock.lock();
            try
            {
                i++;
            }
            finally
            {
                lock.unlock();
                lock.unlock();
            }
        }

但一定要记得获得多少锁也要释放多少锁。

另外,重入锁是可以被中断的,比如设置两个锁AB,线程一先获得A再获得B,线程二先获得B再获得A,此时容易死锁,可以通过中断的方式退出

lock.lockInterruptibly();

为了避免死锁问题,重入锁还提供了一个限时等待的方法

lock.tryLock(timeout, unit)

为了避免饥饿问题,重入锁还可以设置公平锁,在构造的时候。

public static ReentrantLock lock=new ReentrantLock(true) ;

下面的一张图是对重入锁这些方法的总结

 

condition之于重入锁,相当于wait,notify之于synchronize。用法也差不多。

condition可以通过lock来实例化,两个await() signal()方法和synchronize的两个对应

public static ReentrantLock lock=new ReentrantLock(true) ;
public static Condition condition=lock.newCondition();
condition.await();
condition.signal();

 

posted @ 2018-07-27 15:59  蒋曾  阅读(137)  评论(0编辑  收藏  举报