首页 > 其他 > 详细

聊聊Lock接口的lock()和lockInterruptible()有什么区别?

时间:2021-05-03 22:45:28      阅读:36      评论:0      收藏:0      [点我收藏+]
lock()和lockInterruptible()都表示获取锁,唯一区别是,当A线程调用lock()方法获取锁没有成功而进入等待锁的状态时,若接着调用该A线程的interrupt()方法中断该线程的等待:
  • 如果A线程是通过lock()获取锁失败而进入等待状态的:则A线程不会马上执行自己的interrupt()方法去中断等待,而是继续等待获取锁(同时把中断命令放入等待队列), 获取到锁之后才响应自己的interrupt()方法去中断等待(从等待丢列中拿出中断命令执行)。获取锁之后,若A线程没有处于等待状态而调用interrupt()方法,是不会发生任何事情的,若获取锁之后A刚刚好又进入了等待状态,则执行等待丢列中的中断命令就会让A抛出InterruptedException()异常去中断等待
  • 如果A线程是想通过lockInterruptible()获取锁失败而进入等待状态的:则A线程会马上响应自己的interrupt()方法抛出InterruptedException 异常去中断等待,此时在finally里处理该异常,从而接着执行其他的代码

使用lockInterruptible()获取锁的例子:

 1  2 public class LockTest {
 3     private Lock lock = new ReentrantLock();
 4     public void doBussiness() {
 5         String name = Thread.currentThread().getName();
 6  
 7         try {
 8             System.out.println(name + " 开始获取锁");
 9             lock.lockInterruptibly();//获取锁,可以调interrupt()中断等待
10             System.out.println(name + " 得到锁");
11             System.out.println(name + " 开工干活");
12             for (int i=0; i<5; i++) {
13                 Thread.sleep(1000);
14                 System.out.println(name + " : " + i);
15             }
16         } catch (InterruptedException e) {
17             //用lockInterruptibly()获取锁,必须处理可能调用interrupt()而抛出的InterruptedException异常
18             System.out.println(name + " 被中断");
19             System.out.println(name + " 做些别的事情");
20         } finally {
21             try {
22                 lock.unlock();
23                 System.out.println(name + " 释放锁");
24             } catch (Exception e) {
25                 System.out.println(name + " : 没有得到锁的线程运行结束");
26             }
27         }
28     }
29  
30     public static void main(String[] args) throws InterruptedException {
31  
32         LockTest lockTest = new LockTest();
33  
34         Thread t0 = new Thread(
35                 new Runnable() {
36                     public void run() {
37                         lockTest.doBussiness();
38                     }
39                 }
40                 );
41  
42         Thread t1 = new Thread(
43                 new Runnable() {
44                     public void run() {
45                         lockTest.doBussiness();
46                     }
47                 }
48                 );
49  
50         // 启动线程t1
51         t0.start();
52         Thread.sleep(10);
53         // 启动线程t2
54         t1.start();
55         Thread.sleep(100);
56         // 线程t1没有得到锁,中断t1的等待
57         t1.interrupt();
58     }
59 }
60 #运行结果:
61 Thread-0 开始获取锁
62 Thread-0 得到锁
63 Thread-0 开工干活
64 Thread-1 开始获取锁
65 Thread-1 被中断  //线程t1用lockInterruptible()获取锁失败而进入等待时,主线程调用t1.interrupt()使该t1抛出异常从而中断等待
66 Thread-1 做些别的事情//t1中断等待后接着执行其他的代码
67 Thread-1 : 没有得到锁的线程运行结束
68 Thread-0 : 0
69 Thread-0 : 1
70 Thread-0 : 2
71 Thread-0 : 3
72 Thread-0 : 4
73 Thread-0 释放锁

使用lock()获取锁的例子:

 1 把上面第9行中lock.lockInterruptibly()改为lock.lock(),其他代码不变,则输出结果:
 2 
 3 Thread-0 开始获取锁
 4 Thread-0 得到锁
 5 Thread-0 开工干活
 6 Thread-1 开始获取锁  //t0已经获取到了锁,所以t1只能进入等待状态(线程没有获取到锁会进入等待状态)。因为t1是调用lock.lock()获取锁的,所以即便主线程调用t1.interrupt()方法,t1也不会马上响应中断(即抛出InterruptedException异常来中断自己的等待状态),而是直到拿到锁之后才会响应中断
 7 Thread-0 : 0
 8 Thread-0 : 1
 9 Thread-0 : 2
10 Thread-0 : 3
11 Thread-0 : 4  
12 Thread-1 得到锁  //t0打印完后已经执行了lock.unlock()释放了锁,要不然t1是拿不到锁的。同时t0还没来得及执行上面第23行代码用System打印出“Thread-0 释放锁”,时间片就轮给了t1,所以这行代码是t1执行输出的
13 Thread-1 开工干活
14 Thread-1 被中断 //由于t1拿到锁后才会去响应中断,所以上面第13行Thread.sleep(1000)在t1拿到锁之后又让t1进入了等待状态,此时t1刚刚好执行响应中断,故抛出InterruptedException异常来响应中断
15 Thread-1 做些别的事情
16 Thread-0 释放锁
17 Thread-1 释放锁  //t0早就释放了锁,在这里重新获得了时间片进行打印操作

 

聊聊Lock接口的lock()和lockInterruptible()有什么区别?

原文:https://www.cnblogs.com/afei1759/p/14728144.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!