2.4.线程的同步和协作_读写锁
2014-04-23 12:14
183 查看
读写锁
锁机制引入了读写锁特性:ReadWriteLock接口和唯一的实现类ReentrantReadWriteLock。读写锁是锁机制的最大改进之一,提供了将读和写分开处理的能力。ReentrantReadWriteLock有两个锁,一个是读操作锁,另一个是写操作锁。读操作锁允许多个线程同时访问,但是写操作锁只允许一个线程进行访问,在一个线程执行写操作时,其他线程不能执行读操作。在进行写操作加锁时,必须等待所有的读操作锁都释放之后才能实施写操作加锁。我们依然以计数器的例子来说明ReadWriteLock的用法,假设只有一个线程更新计数器的值,通过ReadWriteLock的writeLock方法取得写操作锁,进行写操作的同步;其他线程都是读取计数器的值用来显示,通过ReadWriteLock的readLock方法取得读操作锁,进行读操作的同步。示例代码如下:
public class ReadWriteCountDemo { public static void main(String[] args){ ReadWriteCounter counter = new ReadWriteCounter(); CountReader reader = new CountReader(counter); CountWriter writer = new CountWriter(counter); System.out.println("main:创建读写线程"); Thread r1 = new Thread(reader); Thread r2 = new Thread(reader); Thread r3 = new Thread(reader); Thread w = new Thread(writer); System.out.println("main:启动读写线程"); w.start(); r1.start(); r2.start(); r3.start(); System.out.println("main:等待读写线程"); try { w.join(); r1.join(); r2.join(); r3.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("main:退出"); } } class CountReader implements Runnable{ ReadWriteCounter counter = null; CountReader(ReadWriteCounter counter){ this.counter = counter; } @Override public void run() { for(int i=0 ;i<5; i++){ long value = counter.get(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } class CountWriter implements Runnable{ ReadWriteCounter counter = null; CountWriter(ReadWriteCounter counter){ this.counter = counter; } @Override public void run() { for(int i=0; i<5; i++){ counter.increase(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } class ReadWriteCounter{ private long count = 0; private ReadWriteLock lock = new ReentrantReadWriteLock(); public void increase(){ System.out.println("写操作:申请写操作锁"); lock.writeLock().lock(); System.out.println("写操作:获得写操作锁"); count++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println("写操作:完成更新计数器。计数器值:" + count + ",释放写操作锁"); lock.writeLock().unlock(); } } public long get(){ System.out.println(Thread.currentThread().getName() + ":读操作:申请读操作锁"); lock.readLock().lock(); System.out.println(Thread.currentThread().getName() + ":读操作:获得读操作锁"); long tmp = count; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println(Thread.currentThread().getName() + ":读操作:计数器值" + tmp + ",释放读操作锁"); lock.readLock().unlock(); } return tmp; } }
程序执行日志:
main:创建读写线程 main:启动读写线程 写操作:申请写操作锁 写操作:获得写操作锁 main:等待读写线程 Thread-1:读操作:申请读操作锁 Thread-2:读操作:申请读操作锁 Thread-0:读操作:申请读操作锁 写操作:完成更新计数器。计数器值:1,释放写操作锁 Thread-1:读操作:获得读操作锁 Thread-2:读操作:获得读操作锁 Thread-0:读操作:获得读操作锁 写操作:申请写操作锁 Thread-0:读操作:计数器值1,释放读操作锁 Thread-2:读操作:计数器值1,释放读操作锁 Thread-1:读操作:计数器值1,释放读操作锁 写操作:获得写操作锁 Thread-0:读操作:申请读操作锁 Thread-2:读操作:申请读操作锁 Thread-1:读操作:申请读操作锁 写操作:完成更新计数器。计数器值:2,释放写操作锁 Thread-0:读操作:获得读操作锁 Thread-2:读操作:获得读操作锁 Thread-1:读操作:获得读操作锁 写操作:申请写操作锁 Thread-2:读操作:计数器值2,释放读操作锁 Thread-1:读操作:计数器值2,释放读操作锁 Thread-0:读操作:计数器值2,释放读操作锁 写操作:获得写操作锁 Thread-2:读操作:申请读操作锁 Thread-0:读操作:申请读操作锁 Thread-1:读操作:申请读操作锁 写操作:完成更新计数器。计数器值:3,释放写操作锁 Thread-2:读操作:获得读操作锁 Thread-0:读操作:获得读操作锁 Thread-1:读操作:获得读操作锁 Thread-0:读操作:计数器值3,释放读操作锁 Thread-2:读操作:计数器值3,释放读操作锁 写操作:申请写操作锁 Thread-1:读操作:计数器值3,释放读操作锁 写操作:获得写操作锁 Thread-2:读操作:申请读操作锁 Thread-1:读操作:申请读操作锁 Thread-0:读操作:申请读操作锁 写操作:完成更新计数器。计数器值:4,释放写操作锁 Thread-2:读操作:获得读操作锁 Thread-1:读操作:获得读操作锁 Thread-0:读操作:获得读操作锁 Thread-2:读操作:计数器值4,释放读操作锁 写操作:申请写操作锁 Thread-0:读操作:计数器值4,释放读操作锁 Thread-1:读操作:计数器值4,释放读操作锁 写操作:获得写操作锁 Thread-1:读操作:申请读操作锁 Thread-2:读操作:申请读操作锁 Thread-0:读操作:申请读操作锁 写操作:完成更新计数器。计数器值:5,释放写操作锁 Thread-1:读操作:获得读操作锁 Thread-0:读操作:获得读操作锁 Thread-2:读操作:获得读操作锁 Thread-0:读操作:计数器值5,释放读操作锁 Thread-2:读操作:计数器值5,释放读操作锁 Thread-1:读操作:计数器值5,释放读操作锁 main:退出
可以看到:
进行写操作加锁时,必须等待所有的读操作锁释放。
写操作加锁后,其他读操作必须等待写操作锁释放之后,才能再进行读操作加锁。
相关文章推荐
- linux线程间同步(1)读写锁
- 2.3.线程的同步和协作_锁
- linux信号量实现线程读写同步
- 《Java高并发程序设计》学习 --3.1多线程的团队协作:同步控制
- 同步队列协作线程
- Java总结(十)—实现Runnable接口创建线程,线程安全同步,死锁(哲学家进餐问题),读写锁
- 2.1.线程的同步和协作_基本同步
- 2.使用synchronized关键字实现多线程的同步和互斥(不同线程同时读写同一数据)
- 线程与同步之三——读写锁
- 2.2.线程的同步和协作_基本协作
- 2.5.线程的同步和协作_锁的公平性
- linux线程间同步(1)读写锁
- java中线程的同步:(互斥,协作)
- 线程间的协作同步
- Java线程(四):JUC包线程互斥与同步以及读写锁
- .NET组件程序设计 第8章 多线程和并发管理 同步线程_互锁,读写锁
- Linux线程浅析[线程的同步和互斥之线程读写锁]
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量
- linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量