reentrantlock用于替代synchronized

1.①使用reentrantlock可以完成同样的功能
   ②需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍)
   ③使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放

Lock lock = new ReentrantLock();

void m1() {
    try {
        lock.lock(); //synchronized(this)
        for (int i = 0; i < 10; i++) {
            TimeUnit.SECONDS.sleep(1);

            System.out.println(i);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

2.使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待

/**
 * 使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行
 * 可以根据tryLock的返回值来判定是否锁定
 * 也可以指定tryLock的时间,由于tryLock(time)抛出异常,所以要注意unclock的处理,必须放到finally中
 */
void m2() {
    /*
    boolean locked = lock.tryLock();
    System.out.println("m2 ..." + locked);
    if(locked) lock.unlock();
    */
    
    boolean locked = false;
    
    try {
        locked = lock.tryLock(5, TimeUnit.SECONDS);
        System.out.println("m2 ..." + locked);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        if(locked) lock.unlock();
    }
    
}

3.使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应;在一个线程等待锁的过程中,可以被打断

Thread t2 = new Thread(()->{
    try {
        //lock.lock();
        lock.lockInterruptibly(); //可以对interrupt()方法做出响应
        System.out.println("t2 start");
        TimeUnit.SECONDS.sleep(5);
        System.out.println("t2 end");
    } catch (InterruptedException e) {
        System.out.println("interrupted!");
    } finally {
        lock.unlock();
    }
});
t2.start();

4.ReentrantLock还可以指定为公平锁

private static ReentrantLock lock=new ReentrantLock(true); //参数为true表示为公平锁,请对比输出结果
public void run() {
    for(int i=0; i<100; i++) {
        lock.lock();
        try{
            System.out.println(Thread.currentThread().getName()+"获得锁");
        }finally{
            lock.unlock();
        }
    }
}
原文地址:https://www.cnblogs.com/ganchuanpu/p/7837321.html