1、可重入锁ReentrantLock,相当于synchronized块,为临界区提供互斥访问机制。
(1)相关的接口
创建一个可重入锁
Lock lock = new ReentrantLock(); |
请求锁,如果锁被当前另一个线程持有,则阻塞。
释放锁
非阻塞型lock()
(2)使用基本结构
locker.lock(); try{ }finally{ locker.unlock(); } |
这种结构保证在任何时刻只有一个线程能够进入临界区,如果一个线程锁住了锁对象,其他任何线程在调用lock时,都会被阻塞,直到第一个线程释放锁对象。而且无论try块是否抛出异常,都会执行finally block,解锁locker。
(3)锁的可重入性
锁是可重入的,线程能够重复地获取它已经拥有的锁。锁对象维护一个持有计数(hold count)来追踪对lock方法的嵌套调用。线程在每次调用lock后都要调用unlock来释放锁。由于这个特性,被一个锁保护的代码可以调用另一个使用相同锁的方法。
(4)示例代码:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class WorkerOne extends Thread{ private Lock locker; public WorkerOne (Lock locker){ this.locker = locker; } public void run(){ locker.lock(); try{ System.out.println(Thread.currentThread().getName()+":step into critical section"); }finally{ locker.unlock(); } } } class WorkerTwo extends Thread{ private Lock locker; public WorkerTwo (Lock locker){ this.locker = locker; } public void sayHello(){ locker.lock(); try{ System.out.println(Thread.currentThread().getName()+":call sayHello()"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally{ locker.unlock(); } } public void run(){ locker.lock(); try{ System.out.println(Thread.currentThread().getName()+":setp into critical section"); sayHello(); }finally{ locker.unlock(); } } } public class Test5 { public static void main(String[] args) { Lock locker = new ReentrantLock(); WorkerOne wo= new WorkerOne(locker); wo.setName("WorkerOne"); WorkerTwo wt = new WorkerTwo(locker); wt.setName("WorkerTwo"); wt.start(); wo.start(); } } |