JDK 5.0 Concurrency Utilities 并发处理 ReentrantLock 可重入锁
2011-10-25 14:16
549 查看
ReentrantLock -- 可重入的锁 可重入锁指在同一个线程中,可以重入的锁。当然,当这个线程获得锁后,其他线程将等待这个锁被释放后,才可以获得这个锁。 构造器:ReentrantLock(boolean fair): 布尔值用来表示,创建的这个锁是公平的锁,还是自由竞争的锁。所谓公平的锁,是指,各个希望获得所得线程获得锁的顺序是按到达的顺序获得,还是自由竞争获得。 通常的使用方法: ReentrantLock lock = new ReentrantLock(); // not a fair lock lock.lock(); try { // synchronized do something } finally { lock.unlock(); } 一个典型的例子:先测试可重入锁的重入特性,然后创建3个线程,每个线程启动后,尝试获取锁,获取锁后对共享数据 + 1,然后显示chula import java.util.Calendar; import java.util.concurrent.locks.ReentrantLock; public class TestLock { private ReentrantLock lock = null; // 用于线程同步访问的共享数据 public int data = 100; public TestLock() { // 创建一个自由竞争的可重入锁 lock = new ReentrantLock(); } public static void main(String[] args) { TestLock tester = new TestLock(); // 测试可重入,函数testReentry() 执行获取锁后,显示信息的功能 tester.testReentry(); // 能执行到这里而不阻塞,表示锁可重入 tester.testReentry(); // 再次重入 tester.testReentry(); // 释放重入测试的锁,要按重入的数量解锁,否则其他线程无法获取该锁。 tester.getLock().unlock(); tester.getLock().unlock(); tester.getLock().unlock(); // 启动3个线程测试在锁保护下的共享数据data的访问 tester.test(); } public ReentrantLock getLock() { return lock; } public void test() { new Thread(new workerThread(this)).start(); new Thread(new workerThread(this)).start(); new Thread(new workerThread(this)).start(); } public void testReentry() { lock.lock(); Calendar now = Calendar.getInstance(); System.out.println(now.getTime() + " " + Thread.currentThread() + " get lock."); } // 线程调用的方法 public void testRun() throws Exception { // 加锁 lock.lock(); Calendar now = Calendar.getInstance(); try { // 获取锁后显示 当前时间 当前调用线程 共享数据的值(并使共享数据 + 1) System.out.println(now.getTime() + " " + Thread.currentThread() + " accesses the data " + data ++); // 模拟其他处理,这里假设休眠一下 Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } finally { // 解锁 lock.unlock(); } } } // 工作线程,调用TestServer.testRun class workerThread implements Runnable { private TestLock tester = null; public workerThread(TestLock testLock) { this.tester = testLock; } public void run() { // 循环调用,尝试加锁,并对共享数据+1,然后显示出来 while (true) { try { // 调用tester.testRun() tester.testRun(); } catch (Exception e) { e.printStackTrace(); } } } } 程序运行结果: Tue Jan 24 13:41:45 CST 2006 Thread[main,5,main] get lock. Tue Jan 24 13:41:46 CST 2006 Thread[main,5,main] get lock. Tue Jan 24 13:41:46 CST 2006 Thread[main,5,main] get lock. Tue Jan 24 13:41:46 CST 2006 Thread[Thread-0,5,main] accesses the data 100 Tue Jan 24 13:41:46 CST 2006 Thread[Thread-1,5,main] accesses the data 101 Tue Jan 24 13:41:47 CST 2006 Thread[Thread-2,5,main] accesses the data 102 Tue Jan 24 13:41:47 CST 2006 Thread[Thread-2,5,main] accesses the data 103 Tue Jan 24 13:41:48 CST 2006 Thread[Thread-2,5,main] accesses the data 104 Tue Jan 24 13:41:48 CST 2006 Thread[Thread-0,5,main] accesses the data 105 Tue Jan 24 13:41:49 CST 2006 Thread[Thread-0,5,main] accesses the data 106 Tue Jan 24 13:41:49 CST 2006 Thread[Thread-0,5,main] accesses the data 107 Tue Jan 24 13:41:50 CST 2006 Thread[Thread-0,5,main] accesses the data 108 Tue Jan 24 13:41:50 CST 2006 Thread[Thread-1,5,main] accesses the data 109 Tue Jan 24 13:41:51 CST 2006 Thread[Thread-1,5,main] accesses the data 110 前三行表示main线程,重入3次获得该锁。 第四行表示Thread-0线程,先获得锁,使共享数据+1,然后显示信息,然后释放锁。 第五行表示Thread-1线程,获得锁,使共享数据+1,然后显示信息,然后释放锁。 由程序输出的信息可以知道,各线程获得锁的顺序,是自由竞争的结果。 如果将 lock = new ReentrantLock(); 改为:lock = new ReentrantLock(true); 将看到如下的结果: Tue Jan 24 13:47:29 CST 2006 Thread[main,5,main] get lock. Tue Jan 24 13:47:30 CST 2006 Thread[main,5,main] get lock. Tue Jan 24 13:47:30 CST 2006 Thread[main,5,main] get lock. Tue Jan 24 13:47:30 CST 2006 Thread[Thread-0,5,main] accesses the data 100 Tue Jan 24 13:47:30 CST 2006 Thread[Thread-1,5,main] accesses the data 101 Tue Jan 24 13:47:31 CST 2006 Thread[Thread-2,5,main] accesses the data 102 Tue Jan 24 13:47:31 CST 2006 Thread[Thread-0,5,main] accesses the data 103 Tue Jan 24 13:47:32 CST 2006 Thread[Thread-1,5,main] accesses the data 104 Tue Jan 24 13:47:32 CST 2006 Thread[Thread-2,5,main] accesses the data 105 Tue Jan 24 13:47:33 CST 2006 Thread[Thread-0,5,main] accesses the data 106 Tue Jan 24 13:47:33 CST 2006 Thread[Thread-1,5,main] accesses the data 107 Tue Jan 24 13:47:34 CST 2006 Thread[Thread-2,5,main] accesses the data 108 Tue Jan 24 13:47:34 CST 2006 Thread[Thread-0,5,main] accesses the data 109 Tue Jan 24 13:47:35 CST 2006 Thread[Thread-1,5,main] accesses the data 110 可以看到各线程获得锁的顺序,是按线程获得锁的顺序。 (注: new Thread(new workerThread()).start(); 并不是表示线程启动的顺序,就是线程获得锁的顺序)
相关文章推荐
- JDK 5.0 Concurrency Utilities 并发处理(1)ReentrantLock 可重入锁
- JDK 5.0 Concurrency Utilities 并发处理(3)ReadWriteLock 读写锁
- JDK 5.0 Concurrency Utilities 并发处理(3)ReadWriteLock 读写锁
- JDK 5.0 Concurrency Utilities 并发处理(4)Semaphore 信号量
- jdk源码解读-并发包-Lock-ReentrantReadWriteLock(1)-整体介绍以及读锁的lock 和 unlock 解析
- jdk源码解读-并发包-Lock-ReentrantLock(1)--lock()与unlock()方法走读
- Java乐观锁悲观锁、synchronized,重入锁 (ReentrantLock)处理并发(互斥同步、非互斥同步)
- JDK并发包---(3)重入锁ReentrantLock:锁申请等待限时
- JDK并发包---(8)ReadWriteLock读写锁:替换ReentrantLock,提高性能
- JDK并发包---(4)重入锁ReentrantLock:锁申请无限等待且不会产生死锁
- Java高并发程序-Chapter3 JDK并发包(第九讲)同步控制之 ReentrantLock 重用锁
- JDK并发包---(5)重入锁ReentrantLock:公平锁
- java高并发程序设计总结三:JDK并发包之ReentrantLock重入锁
- Java高并发程序-Chapter3 JDK并发包(第十七讲)同步控制之ReentrantLock 的实现
- JDK并发包---(6)重入锁ReentrantLock搭档:Condition条件
- Java 并发问题的处理神器:ReentrantReadWriteLock
- JDK并发包---(1)重入锁ReentrantLock:基本使用
- JDK 5.0 Concurrency Utilities 并发处理(2)Condition 条件变量
- JDK并发包---(2)重入锁ReentrantLock:中断响应
- Java 理论与实践: JDK 5.0 中更灵活、更具可伸缩性的锁定机制(ReentrantLock)