【Java并发编程实战】– 使用读写锁实现同步数据访问 lock_2
2017-09-08 00:00
996 查看
一、概述
ReentrantReadWriteLock(读写锁),父接口:ReadWriteLock。这个类 有2个锁,一个是 读操作锁,另一个是 写操作锁。使用读操作锁时可以允许多个线程同时访问,但是使用写操作锁时只允许一个线程进行。在一个线程执行写操作时,其他线程不能够执行读操作。
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
二、实现
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Queue3{ private int data = 0;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); public void get(){ rwl.readLock().lock();//上读锁,其他线程只能读不能写 System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " be ready to read data!"); try { Thread.sleep((long)(Math.random()*1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " have read data :" + data); rwl.readLock().unlock(); //释放读锁,最好放在finnaly里面 } public void put(int data){ rwl.writeLock().lock();//上写锁,不允许其他线程读也不允许写 System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " be ready to write data!"); try { Thread.sleep((long)(Math.random()*1000)); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " have write data: " + data); rwl.writeLock().unlock();//释放写锁 } }
import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; public class MyRunnable implements Runnable{ private int flat; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); private Queue3 queue3; Random random = new Random(); public MyRunnable(Queue3 queue3, int flat) { this.queue3 = queue3; this.flat = flat; } public void run() { if(flat == 0){ // 读操作 queue3.get(); }else if(flat == 1){ // 写操作 int data = random.nextInt(10); System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " 随机数为:" + data); queue3.put(data); }else{ System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + "操作有误!"); } } }
public class ReadWriteLockTest { public static void main(String[] args) { Queue3 queue3 = new Queue3(); MyRunnable myReader = new MyRunnable(queue3, 0); // 读操作 MyRunnable myWriter = new MyRunnable(queue3, 1); // 写操作 for(int i=0;i<3;i++){ Thread thread = new Thread(myReader); thread.start(); } Thread thread = new Thread(myWriter); thread.start(); } }
//console结果: 2017-09-08 03:56:35 Thread-1 be ready to read data! 2017-09-08 03:56:35 Thread-2 be ready to read data! 2017-09-08 03:56:35 Thread-0 be ready to read data! 2017-09-08 03:56:35 Thread-3 随机数为:6 2017-09-08 03:56:35 Thread-1 have read data :0 2017-09-08 03:56:35 Thread-2 have read data :0 2017-09-08 03:56:35 Thread-0 have read data :0 2017-09-08 03:56:35 Thread-3 be ready to write data! 2017-09-08 03:56:36 Thread-3 have write data: 6
相关文章推荐
- 【Java并发编程实战】– 使用锁实现同步 lock_1
- Java并发学习之十五——使用读写锁同步数据访问
- 【Java并发编程实战】– 使用非依赖属性实现同步
- java并发编程之线程同步基础(二)使用锁实现同步
- 使用读写锁实现同步数据访问
- 【Java并发编程实战】– 在同步代码中使用条件
- 并发编程--使用读写锁实现同步数据访问
- java并发编程实战手册第二章使用读写锁实现同步数据访问
- java多线程-使用ReadWriteLock同步数据访问
- 并发编程实战 2.1. 使用synchronized实现同步
- Java并发编程:重入锁(ReentranceLock )、读写锁(ReadWriteLock)代码实现
- Java并发学习之十五——使用读写锁同步数据訪问
- 【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列
- java读写锁实现数据同步访问
- java并发包中的Condition和Lock 取代Synchronized、wait、notify/notifyAll实现线程的同步与互斥
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析
- Java实现生产者与消费者(四)(多生产者与多消费者使用lock同步锁)
- 【Java并发编程实战】—–“J.U.C”:ReentrantLock之二lock方法分析
- Java并发编程笔记 使用阻塞队列实现生产者-消费者模型