Lock应用之 可中断

Thread.interrupt()方法可用于中断指定线程,但线程并不是在任何状态下可被立即中断,一般只有当线程处于阻塞状态(调用wait(),join(),sleep()等方法)时才会被立即中断,如果线程处于不可被立即中断状态,那么Thread.interrupt()只会标志线程的中断状态,以便后续操作用于判断,即isInterrupted()方法会返回true.


线程等待获取内部锁的时候,是一种不可立即中断状态,即线程不会立即响应中断而是会继续等待,这种无义无反顾的等待可能会造成资源浪费或者死锁等问题,后果非常严重。新Lock锁提供了等待锁资源时可立即响应中断的lockInterruptibly()方法和tryLock(long time, TimeUnit unit)方法及其实现,当使用这两个方法去请求锁时,如果主通过Thread.interrupt()对它们发起中断,那么它们会立即响应中断,不再继续等待获取锁,这让主线程(管理调度线程)在特殊情况下可以使用生杀大权,以避免系统陷于死锁状态或者避免资源严重浪费。


tryLock(long time, TimeUnit unit)是加强版的tryLock(),又具有lockInterruptibly()的可被中断特性,既可任其超时主动退出又可中断让其被动退出,很多场合可以使用,但如果想让线程只有当被动中断时才退出,那么就使用lockInterruptibly()方法。


通过测试可以得出以下结论:

  • 内部锁(synchronized) 优先响应锁获取再响应中断

  • Lock.lock() 优先响应锁获取再响应中断

  • Lock.tryLock() 判断锁的状态不可用后马上返回不等待

  • tryLock(long time, TimeUnit unit) 优先响应中断再响应锁获取

  • Lock.lockInterruptibly() 优先响应中断再响应锁获取


代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import  java.util.concurrent.TimeUnit;
import  java.util.concurrent.locks.Lock;
import  java.util.concurrent.locks.ReentrantLock;
public  class  TestLockInterrupt {
     private  Lock mLock1;
     private  Lock mLock2;
     private  Lock mLock3;
                                                                                                                                                  
     public  TestLockInterrupt(){
         mLock1 =  new  ReentrantLock();
         mLock2 =  new  ReentrantLock();
         mLock3 =  new  ReentrantLock();  
     }
                                                                                                                                                  
     public  void  f(){
         System.out.println(Thread.currentThread().getName() +  ":try to get lock in f()." );
                                                                                                                                                      
         try {
             synchronized ( this ){
                 System.out.println(Thread.currentThread().getName() +  ":get the lock." );
                                                                                                                                                              
                 if (Thread.currentThread().isInterrupted()){
                     System.out.println(Thread.currentThread().getName() +  ":already marked as interrupted but still running." );
                 }
                                                                                                                                                              
                 TimeUnit.SECONDS.sleep( 100 );
             }
                                                                                                                                                          
             System.out.println(Thread.currentThread().getName() +  ":release the lock." );
         }
         catch (InterruptedException e){
             System.out.println(Thread.currentThread().getName() +  ":interrupted." );
         }          
     }
                                                                                                                                                  
     public  void  fWithLock(){
         System.out.println(Thread.currentThread().getName() +  ":try to get lock in fWithLock()." );
                                                                                                                                                      
         mLock1.lock();
         try {
             System.out.println(Thread.currentThread().getName() +  ":get the lock." );
                                                                                                                                                          
             if (Thread.currentThread().isInterrupted()){
                 System.out.println(Thread.currentThread().getName() +  ":already marked as interrupted but still running." );
             }
                                                                                                                                                          
             TimeUnit.SECONDS.sleep( 100 );
         }
         catch (InterruptedException e){
             System.out.println(Thread.currentThread().getName() +  ":interrupted." );
         }
         finally {
             mLock1.unlock();
             System.out.println(Thread.currentThread().getName() +  ":release the lock." );
         }          
     }
                                                                                                                                                  
     public  void  fWithTryLock(){
         System.out.println(Thread.currentThread().getName() +  ":try to get lock in fWithTryLock()." );
                                                                                                                                                              
         try {
             if (mLock2.tryLock( 50 , TimeUnit.SECONDS)){
                 try {
                     System.out.println(Thread.currentThread().getName() +  ":get the lock." );
                                                                                                                                                                  
                     if (Thread.currentThread().isInterrupted()){
                         System.out.println(Thread.currentThread().getName() +  ":already marked as interrupted but still running." );
                     }
                                                                                                                                                                  
                     TimeUnit.SECONDS.sleep( 100 );
                 }
                 finally {
                     mLock2.unlock();
                     System.out.println(Thread.currentThread().getName() +  ":release the lock." );
                 }
             }      
         }
         catch (InterruptedException e){
             System.out.println(Thread.currentThread().getName() +  ":interrupted." );
         }                  
     }
                                                                                                                                                  
     public  void  fWithLockInterruptibly(){
         System.out.println(Thread.currentThread().getName() +  ":try to get lock in fWithLockInterruptibly()." );
                                                                                                                                                      
         try {       
             mLock3.lockInterruptibly();
             System.out.println(Thread.currentThread().getName() +  ":get the lock." );
                                                                                                                                                          
             try {
                 if (Thread.currentThread().isInterrupted()){
                     System.out.println(Thread.currentThread().getName() +  ":already marked as interrupted but still running." );
                 }
                                                                                                                                                              
                 TimeUnit.SECONDS.sleep( 100 );
             }
             finally {
                 mLock3.unlock();
                 System.out.println(Thread.currentThread().getName() +  ":release the lock." );
             }      
         }
         catch (InterruptedException e){
             System.out.println(Thread.currentThread().getName() +  ":interrupted." );
         }          
     }
     private  class  Worker  implements  Runnable{
         private  int  index;
                                                                                                                                                      
         public  Worker( int  index){
             this .index = index;
         }
                                                                                                                                                      
         @Override
         public  void  run() {
             switch (index){
             case  1 :
                 f();
                 break ;
             case  2 :
                 fWithLock();
                 break ;
             case  3 :
                 fWithTryLock();
                 break ;
             case  4 :
                 fWithLockInterruptibly();
                 break ;
             }
         }  
     }
                                                                                                                                                  
     public  static  void  main(String[] args) {
         TestLockInterrupt testLockInterrupt =  new  TestLockInterrupt();
                                                                                                                                                      
         for ( int  i= 1 ; i<= 4 ; i++){
             Thread t1 =  new  Thread(testLockInterrupt. new  Worker(i));
             Thread t2 =  new  Thread(testLockInterrupt. new  Worker(i));
                                                                                                                                                          
             t1.start();
             t2.start();
                                                                                                                                                          
             t1.interrupt();
             t2.interrupt();
         }  
     }
}


代码输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Thread- 0 : try  to  get  lock  in  f().
Thread- 1 : try  to  get  lock  in  f().
Thread- 1 : get  the lock.
Thread- 3 : try  to  get  lock  in  fWithLock().
Thread- 1 :already marked  as  interrupted but still running.
Thread- 3 : get  the lock.
Thread- 3 :already marked  as  interrupted but still running.
Thread- 7 : try  to  get  lock  in  fWithLockInterruptibly().
Thread- 2 : try  to  get  lock  in  fWithLock().
Thread- 1 :interrupted.
Thread- 7 :interrupted.
Thread- 3 :interrupted.
Thread- 3 :release the lock.
Thread- 2 : get  the lock.
Thread- 2 :already marked  as  interrupted but still running.
Thread- 2 :interrupted.
Thread- 2 :release the lock.
Thread- 4 : try  to  get  lock  in  fWithTryLock().
Thread- 4 :interrupted.
Thread- 0 : get  the lock.
Thread- 0 :already marked  as  interrupted but still running.
Thread- 0 :interrupted.
Thread- 5 : try  to  get  lock  in  fWithTryLock().
Thread- 5 :interrupted.
Thread- 6 : try  to  get  lock  in  fWithLockInterruptibly().
Thread- 6 :interrupted.




     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1301184,如需转载请自行联系原作者


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值