package com.neutron.t17;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* ReentrantLock用于替代synchronized
* 案例中由于m1锁定this,只有m1执行完毕后,m2才能执行
* 复习synchronized最原始的语义
*
* 使用ReentrantLock可以完成同样功能
* 需要注意的内容是:必须手动释放锁。
* 使用synchronized如果遇到异常,jvm会自动释放锁;但是lock必须手动释放锁,因此常常在finally中释放锁
*
* 可以使用ReentrantLock进行尝试锁定tryLock,如果无法锁定或在指定时间内无法锁定,线程可以决定继续等待
*
* 使用ReentrantLock可以调用lockInterruptibly方法,可以对线程的interrupted方法做出响应。
* 在一个线程等待锁的过程中被打断。
*/
public class T174 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
try {
lock.lock();
System.out.println("t1..start");
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
System.out.println("t1..end");
} catch (InterruptedException e) {
System.out.println("interrupted1");
} finally {
lock.unlock();
}
}, "t1");
t1.start();
Thread t2 = new Thread(() -> {
/*
判断t2线程是否获取锁,但是如何判断呢?
除了tryLock可以返回boolean,其他方法没有boolean可以返回
下面的locked无法判断线程是否拿到了锁,如果你知道可以告诉一下我,谢谢
*/
boolean locked = false;
try {
//lock.lock(); // 如果使用lock.lock()方法,当t1线程执行,那么t2线程是没法打断,只能苦苦等待。
lock.lockInterruptibly(); // 可以对interrupt方法做出响应,此方法可以获取lock,同时允许被打断
System.out.println("t2..start");
TimeUnit.SECONDS.sleep(3);
System.out.println("t2..end");
} catch (InterruptedException e) {
System.out.println("interrupted2");
} finally {
if (locked) {
lock.unlock();
}
}
}, "t2");
t2.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt(); // 打断线程2的等待
}
}
/**
* 执行结果:
* t1..start
interrupted2
同时t1直到执行完毕
*/
/**
* 执行过程解释:
* 1.线程t1获取锁lock,然后去无限期等待,即int的最大值的秒数
* 2.线程t2执行,尝试获取lock,如果使用lock.lock(),那么线程t2永远获取不到锁,通知无法被打断。
* 如果使用lock.lockInterruptibly相当于告诉主线程,如果我获取不到锁,那么就给我打断,不要让我再等待。
* 3.主线程main执行的,看到t2线程无法获取锁,因此打断t2线程。
*/
thread22 - ReentrantLock3
最新推荐文章于 2021-07-06 10:00:11 发布