lock 优先考虑获取锁,待获取锁成功后,才响应中断。
lockInterruptibly 优先考虑响应中断,而不是响应锁的普通获取或重入获取。
ReentrantLock.lockInterruptibly允许在等待时由其它线程调用等待线程的Thread.interrupt方法来中断等待线程的等待而直接返回,这时不用获取锁,而会抛出一个InterruptedException。 ReentrantLock.lock方法不允许Thread.interrupt中断,即使检测到Thread.isInterrupted,一样会继续尝试获取锁,失败则继续休眠。只是在最后获取锁成功后再把当前线程置为interrupted状态,然后再中断线程。
lock.lockInterruptibly()
public class LockTest {
private Lock lock = new ReentrantLock();
public void doSomething() {
String name = Thread.currentThread().getName();
try {
System.out.println(name + ",开始获取锁");
lock.lockInterruptibly();
System.out.println(name + ",得到锁,开工干活");
for (int i = 1; i <= 5; i++) {
Thread.sleep(500);
System.out.println(name + ": " + i);
}
} catch (InterruptedException e) {
System.out.println(name + ",被中断了,抛出异常:" + e);
} finally {
try {
lock.unlock();
System.out.println(name + ",成功释放锁");
} catch (Exception e) {
System.out.println(name + ",释放锁异常:"+ e);
}
}
}
public static void main(String[] args) throws InterruptedException {
LockTest lockTest = new LockTest();
Thread t1 = new Thread(() -> lockTest.doSomething(), "线程一");
Thread t2 = new Thread(() -> lockTest.doSomething(), "线程二");
// 启动线程t1
t1.start();
//让线程一先启动
Thread.sleep(10);
// 启动线程t2
t2.start();
Thread.sleep(100);
// 线程t1没有得到锁,中断t1的等待
System.out.println("主线程执行:t2.interrupt()");
t2.interrupt();
}
}
执行结果:
线程一,开始获取锁
线程一,得到锁,开工干活
线程二,开始获取锁
主线程执行:t2.interrupt()
线程二,被中断了,抛出异常:java.lang.InterruptedException
线程二,释放锁异常:java.lang.IllegalMonitorStateException
线程一: 1
线程一: 2
线程一: 3
线程一: 4
线程一: 5
线程一,成功释放锁
lock.lock()
public class LockTest {
private Lock lock = new ReentrantLock();
public void doSomething() {
String name = Thread.currentThread().getName();
try {
System.out.println(name + ",开始获取锁");
lock.lock();
System.out.println(name + ",得到锁,开工干活");
for (int i = 1; i <= 5; i++) {
Thread.sleep(500);
System.out.println(name + ": " + i);
}
} catch (InterruptedException e) {
System.out.println(name + ",被中断了,抛出异常:" + e);
} finally {
try {
lock.unlock();
System.out.println(name + ",成功释放锁");
} catch (Exception e) {
System.out.println(name + ",释放锁异常:"+ e);
}
}
}
public static void main(String[] args) throws InterruptedException {
LockTest lockTest = new LockTest();
Thread t1 = new Thread(() -> lockTest.doSomething(), "线程一");
Thread t2 = new Thread(() -> lockTest.doSomething(), "线程二");
// 启动线程t1
t1.start();
//让线程一先启动
Thread.sleep(10);
// 启动线程t2
t2.start();
Thread.sleep(100);
// 线程t1没有得到锁,中断t1的等待
System.out.println("主线程执行:t2.interrupt()");
t2.interrupt();
}
}
执行结果:
线程一,开始获取锁
线程一,得到锁,开工干活
线程二,开始获取锁
主线程执行:t2.interrupt()
线程一: 1
线程一: 2
线程一: 3
线程一: 4
线程一: 5
线程一,成功释放锁
线程二,得到锁,开工干活
线程二,被中断了,抛出异常:java.lang.InterruptedException: sleep interrupted
线程二,成功释放锁