文档章节

【Java并发编程实战】– 使用读写锁实现同步数据访问 lock_2

pan_1308
 pan_1308
发布于 2017/09/08 15:55
字数 667
阅读 8
收藏 0

一、概述

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

 

© 著作权归作者所有

共有 人打赏支持
pan_1308
粉丝 4
博文 94
码字总数 58819
作品 0
黄冈
读书笔记之《Java并发编程的艺术》-java中的锁

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
0
【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___
05/06
0
0
Java 使用 happen-before 规则实现共享变量的同步操作

前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结果的影响。按照官方的...

stateIs0
01/20
0
0
Java 8新特性探究(十)StampedLock将是解决同步问题的新宠

Java8就像一个宝藏,一个小的API改进,也足与写一篇文章,比如同步,一直是多线程并发编程的一个老话题,相信没有人喜欢同步的代码,这会降低应用的吞吐量等性能指标,最坏的时候会挂起死机,...

OSC闲人
2014/05/13
0
30
JAVA线程13 - 新特性:Lock和条件变量

一、Lock 1. 概述 Lock是JDK 1.5以后将同步和锁封装成了对象。Lock是对之前synchronized的替代。 Lock接口的实现类:互斥锁ReentrantLock 。 2. synchronized与Lock区别 synchronized对于锁的...

小米米儿小
2014/03/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

idea新建springCloud项目(5)- 订单服务

1.创建订单api,如下: 2.创建订单实现逻辑 3.新建订单、订单商品表 -- 订单 create table `order_master` ( `order_id` varchar(32) not null, `buyer_name` varchar(32) not null comment......

monroeCode
14分钟前
0
1
游戏开发经验谈(二):对战类全球服游戏的设计与实现

上篇文章《游戏开发经验谈(一):游戏架构里隐藏的五个坑及其应对方案》,我们主要讲解了游戏架构设计当中隐藏的一些坑及其应对方案,错过的小伙伴可以回溯之前的内容。本期内容,将会重点介...

UCloudTech
24分钟前
0
0
Mysql基本语法

一.联合主键 drop table CONTENT_AND_CATALOG;CREATE TABLE `tobebetter`.`CONTENT_AND_CATALOG` ( `ID` VARCHAR(120) NOT NULL , `CONTENT_ID` VARCHAR(120) , `CA......

我是菜鸟我骄傲
25分钟前
0
0
179. centos7 安装mariadb

1. centos7 中安装mariadb 1.1 执行安装 centos7 自带了mariadb yum -y install mariadb mariadb-server 1.2 启动mariadb systemctl start mariadb 1.3 设置开机启动 systemctl enable maria......

Lucky_Me
33分钟前
0
0
【AI实战】动手训练自己的目标检测模型(YOLO篇)

在前面的文章中,已经介绍了基于SSD使用自己的数据训练目标检测模型(见文章:手把手教你训练自己的目标检测模型),本文将基于另一个目标检测模型YOLO,介绍如何使用自己的数据进行训练。 ...

雪饼
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部