编写多线程Java应用程序并不是小菜一碟。 必须格外小心,因为同步不良会使您的应用程序一s不振。 JVM堆由所有线程共享。 如果多个线程需要同时使用相同的对象或静态类变量,则必须谨慎管理对共享数据的线程访问。 从1.5版开始,JSDK中包含了在并发编程中通常有用的实用程序类。

在Java中, sync关键字用于获取对象的排他锁。 当线程获取对象的锁以进行读取或写入时,其他线程必须等待,直到该对象的锁被释放。 想想一个场景,有许多读取器线程经常读取共享数据,而只有一个写入器线程更新共享数据。 读取时不必排他地锁定对共享数据的访问,因为除非有写入操作,否则可以并行执行多个读取操作。

在本文中,我将提供Java 1.5 API文档中引入的ReadWriteLock接口的示例用法。 在Java Api文档中,它说:

ReadWriteLock维护一对关联的锁,
一种用于只读操作,另一种用于写操作。
读取锁可以由多个读取器线程同时保持,
只要没有作家。 写锁是排他的。

读取器线程可以同时读取共享数据。 读取操作不会阻止其他读取操作。 执行SQL SELECT语句时就是这种情况。 但是写操作是排他的。 这意味着当写入器线程持有用于修改共享数据的锁时,所有读取器和其他写入器均被阻止。

Writer.java此类表示更新共享数据的线程。 Writer使用ReadWriteLock的WriteLock专门锁定对字典的访问。

package deneme.readwritelock;public class Writer extends Thread{private boolean runForestRun = true;private Dictionary dictionary = null;public Writer(Dictionary d, String threadName) {this.dictionary = d;this.setName(threadName);}@Overridepublic void run() {while (this.runForestRun) { String [] keys = dictionary.getKeys();for (String key : keys) {String newValue = getNewValueFromDatastore(key);//updating dictionary with WRITE LOCKdictionary.set(key, newValue);}//update every secondstry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopWriter(){this.runForestRun = false;this.interrupt();}public String getNewValueFromDatastore(String key){//This part is not implemented. Out of scope of this artilereturn "newValue";}}

Reader.java此类表示读取共享数据的线程。

package deneme.readwritelock;public class Reader extends Thread{private Dictionary dictionary = null;public Reader(Dictionary d, String threadName) {this.dictionary = d;this.setName(threadName);}private boolean runForestRun = true;@Overridepublic void run() {while (runForestRun) {String [] keys = dictionary.getKeys();for (String key : keys) {//reading from dictionary with READ LOCKString value = dictionary.get(key);//make what ever you want with the value.System.out.println(key + " : " + value);}//update every secondstry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopReader(){this.runForestRun = false;this.interrupt();}}

Dictionary.java这是一个简单且线程安全的字典。 读操作通过ReadLock进行管理,写操作(更新)通过WriteLock进行管理。

package deneme.readwritelock;import java.util.HashMap;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class Dictionary {private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();private final Lock read  = readWriteLock.readLock();private final Lock write = readWriteLock.writeLock();private HashMap<String, String> dictionary = new HashMap<String, String>();public void set(String key, String value) {write.lock();try {dictionary.put(key, value);} finally {write.unlock();}}public String get(String key) {read.lock();try{return dictionary.get(key);} finally {read.unlock();}}public String[] getKeys(){read.lock();try{String keys[] = new String[dictionary.size()];return dictionary.keySet().toArray(keys);} finally {read.unlock();}}public static void main(String[] args) {Dictionary dictionary = new Dictionary();dictionary.set("java",  "object oriented");dictionary.set("linux", "rulez");Writer writer  = new Writer(dictionary, "Mr. Writer");Reader reader1 = new Reader(dictionary ,"Mrs Reader 1");Reader reader2 = new Reader(dictionary ,"Mrs Reader 2");Reader reader3 = new Reader(dictionary ,"Mrs Reader 3");Reader reader4 = new Reader(dictionary ,"Mrs Reader 4");Reader reader5 = new Reader(dictionary ,"Mrs Reader 5");writer.start();reader1.start();reader2.start();reader3.start();reader4.start();reader5.start();}}

参考:来自我们的JCG合作伙伴 Ilkin Ulas的Java中的ReadWriteLock示例, 您的所有博客都属于我们博客。

翻译自: https://www.javacodegeeks.com/2012/04/java-concurrency-with-readwritelock.html

具有ReadWriteLock的Java并发相关推荐

  1. Java并发编程-ReadWriteLock读写锁

    1.ReadWriteLock介绍 为什么我们有了Lock,还要用ReadWriteLock呢.我们对共享资源加锁之后,所有的线程都将会等待.Lock读操作也锁,写操作也会锁,而对共享资源读的时候,其 ...

  2. Java并发原理抽丝剥茧,读写锁ReadWriteLock实现深入剖析

    跟着作者的65节课彻底搞懂Java并发原理专栏,一步步彻底搞懂Java并发原理. 作者简介:笔名seaboat,擅长工程算法.人工智能算法.自然语言处理.架构.分布式.高并发.大数据和搜索引擎等方面的 ...

  3. Java并发编程71道面试题及答案

    Java并发编程71道面试题及答案 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方 ...

  4. Java并发编程73道面试题及答案——稳了

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户 ...

  5. Java并发编程题库

    文章目录 并发编程三要素? 实现可见性的方法有哪些? 创建线程的有哪些方式? 创建线程的三种方式的对比? Runnable 和 Callable 的区别 Java线程具有五中基本状态 什么是线程池?有 ...

  6. java并发框架支持锁包括,tip/面试题_并发与多线程.md at master · 171437912/tip · GitHub...

    01. java用()机制实现了进程之间的同步执行 A. 监视器 B. 虚拟机 C. 多个CPU D. 异步调用 正解: A 解析: 监视器机制即锁机制 02. 线程安全的map在JDK 1.5及其更 ...

  7. Java并发编程-并发工具包(java.util.concurrent)使用指南(全)

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  8. 多线程面试题_100多线程和Java并发面试问答–最终清单(PDF下载)

    多线程面试题 在这篇文章中,我们将提供有关多线程和Java并发面试问答的综合文章. 编者注:并发始终是开发人员的挑战,编写并发程序可能非常困难. 引入并发时,有很多事情可能会崩溃,并且系统的复杂性会大 ...

  9. 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

    一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比较简单,但是一定要理解. 有几个概念一定要牢记: 加 ...

最新文章

  1. [日常] Go语言圣经-函数递归习题
  2. Resin服务器平台介绍
  3. Http client 请求
  4. 使用Fiddler解析WCF RIA Service传输的数据
  5. Python剑指offer:数组中重复的数字
  6. HDMI_VGA_CBVS同时显示
  7. 三维重建面试0:*SLAM滤波方法的串联综述
  8. 快速构建Windows 8风格应用5-ListView数据控件
  9. daysmatter安卓版_days matter
  10. 一些你可能不知道的 Python 小技巧!
  11. python selenium 点击 报错v_python菜鸟初学selenium+chromedrive,简单点击出错,请指教...
  12. OpenCV学习(17) 细化算法(5)
  13. ssh: connect to host gitee.com port 22: Connection timed out fatal: Could not read from remote repos
  14. 史上最全电脑优化小技巧
  15. python实现泊松分布_Python实现概率分布(二项分布、伯努利分布、泊松分布、几何分布、正态分布等)...
  16. muduo学习笔记:net部分之Http--HttpServer
  17. SecureCRT中常用linux命令
  18. 如何防护DNS欺骗攻击
  19. JavaScript(总结完毕)2021.3.7
  20. USB OTG简介、与普通USB线的区别

热门文章

  1. raid重构原理_5个重构原理示例
  2. dynamodb java_使用Java查询DynamoDB项
  3. java与java ee_Java EE 8 MVC:全局异常处理
  4. java8 函数式编程_使用Javaslang进行Java 8中的函数式编程
  5. junit:junit_简而言之,JUnit:测试隔离
  6. java与java ee_RxJava + Java8 + Java EE 7 + Arquillian =幸福
  7. 免费网络研讨会:Java应用程序中的吞咽异常
  8. 使用RabbitMQ进行消息传递
  9. Java 7:使用NIO.2进行文件过滤–第2部分
  10. 注意Java 8的[Pri​​mitive] Stream.iterate()中的递归