文档章节

【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
粉丝 5
博文 95
码字总数 58819
作品 0
黄冈
私信 提问
【死磕Java并发】—– 死磕 Java 并发精品合集

【死磕 Java 并发】系列是 LZ 在 2017 年写的第一个死磕系列,一直没有做一个合集,这篇博客则是将整个系列做一个概览。 先来一个总览图: 【高清图,请关注“Java技术驿站”公众号,回复:脑...

chenssy
07/22
0
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并发编程之线程安全、线程通信

Java多线程开发中最重要的一点就是线程安全的实现了。所谓Java线程安全,可以简单理解为当多个线程访问同一个共享资源时产生的数据不一致问题。为此,Java提供了一系列方法来解决线程安全问题...

leoliu168
11/07
0
0
【Java并发专题】27篇文章详细总结Java并发基础知识

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

你听___
05/06
0
0
Java 8新特性探究(十)StampedLock将是解决同步问题的新宠

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

OSC闲人
2014/05/13
0
30

没有更多内容

加载失败,请刷新页面

加载更多

tomcat编译超过64k大小的jsp文件报错原因

  今天遇到一个问题,首先是在tomcat中间件上跑的web项目,一个jsp文件,因为代码行数实在是太多了,更新了几个版本之后编译报错了,页面打开都是报500的错误,500的报错,知道http协议返回...

SEOwhywhy
20分钟前
0
0
flutter http 请求客户端

1、pubspec文件管理Flutter应用程序的assets(资源,如图片、package等)。 在pubspec.yaml中,通过网址“https://pub.dartlang.org/packages/http#-installing-tab-”确认版本号后,将http(0...

渣渣曦
21分钟前
0
0
Django基本命令及moduls举例

一、Django基本命令 1.创建项目 django-admin.py startproject mysite 创建后的项目结构:- mysite - mysite #对整个程序进行配置 - init #导入包专用- settings ...

枫叶云
35分钟前
6
0
zabbix安装

rpm -ivh http://repo.webtatic.com/yum/el6/latest.rpm 安装jdk rpm -ivh (自行在网上下载rpm包) 安装php并修改相应参数 yum -y install php56w php56w-gd php56w-mysqlnd php56w-bcmath......

muoushi
37分钟前
4
0
MySQL自增属性auto_increment_increment和auto_increment_offset

MySQL的系统变量或会话变量auto_increment_increment(自增步长)和auto_increment_offset(自增偏移量)控制着数据表的自增列ID。 mysql> show tables;Empty set (0.00 sec)mysql> CREATE TA......

野雪球
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部