【Java并发编程实战】– 使用读写锁实现同步数据访问 lock_2
博客专区 > pan_1308 的博客 > 博客详情
【Java并发编程实战】– 使用读写锁实现同步数据访问 lock_2
pan_1308 发表于2个月前
【Java并发编程实战】– 使用读写锁实现同步数据访问 lock_2
  • 发表于 2个月前
  • 阅读 5
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

一、概述

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

 

共有 人打赏支持
粉丝 5
博文 76
码字总数 56423
×
pan_1308
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: