ReentrantLock保证了只有一个线程可以执行临界区代码。

允许多个线程同时读,但只有一个线程在写,其他线程就必须等待。

使用ReadWriteLock可以解决:

只允许一个线程写入(其他线程既不能写入也不能读取)

没有写入时,多个线程允许同时读(提高性能)

程序运行截图如下:

源码如下:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;class Counter{private ReadWriteLock lock = new ReentrantReadWriteLock();private Lock rlock = lock.readLock();private Lock wlock = lock.writeLock();private int value = 0;public void add(int m){wlock.lock();try{this.value += m;}finally {wlock.unlock();}}public void dec(int m){wlock.lock();try{this.value -= m;}finally {wlock.unlock();}}public int get(){rlock.lock();try{return this.value;}finally {System.out.println("Count get Finally");rlock.unlock();}}
}public class Main1 {final static int LOOP = 100;public static void main(String[] args) throws InterruptedException {final Counter counter = new Counter();Thread t1 = new Thread(){@Overridepublic void run() {for(int i = 0; i < LOOP; i++){counter.add(1);}}};Thread t2 = new Thread(){@Overridepublic void run() {for(int i = 0; i < LOOP; i++){counter.dec(1);}}};t1.start();t2.start();t1.join();t2.join();System.out.println("COUNTER: " + counter.get());}
}

condition中的:

await/signal/signalAll和wait/notify/notifyAll一样。

await()会释放当前锁,进入等待状态。

signal()会唤醒某个等待线程

signalAll()会唤醒所有等待线程

唤醒线程从await()返回后需要重新获得:

程序运行截图如下:

源码如下:

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class TaskQueue{final Queue<String> queue = new LinkedList<String>();final Lock lock = new ReentrantLock();final Condition notEmpty = lock.newCondition();public String getTask() throws InterruptedException {lock.lock();try{while(this.queue.isEmpty()){notEmpty.await();}return queue.remove();}finally {lock.unlock();}}public void addTask(String name){lock.lock();try{this.queue.add(name);notEmpty.signalAll();}finally {lock.unlock();}}
}class WorkerThread extends Thread{TaskQueue taskQueue;public WorkerThread(TaskQueue taskQueue){this.taskQueue = taskQueue;}@Overridepublic void run() {while (!isInterrupted()){String name = "";try{name = taskQueue.getTask();}catch (InterruptedException e) {break;}String result = "HELLO, " + name + " !";System.out.println(result);}}
}public class Main2 {public static void main(String[] args) throws InterruptedException {TaskQueue taskQueue = new TaskQueue();WorkerThread workerThread = new WorkerThread(taskQueue);workerThread.start();taskQueue.addTask("小明");Thread.sleep(1000);taskQueue.addTask("小红");Thread.sleep(1000);taskQueue.addTask("小刚");Thread.sleep(1000);workerThread.interrupt();workerThread.join();System.out.println("END");}
}

Java笔记-ReadWriteLock与Condition的使用相关推荐

  1. 【Java笔记+踩坑】SpringBoot基础3——开发。热部署+配置高级+整合NoSQL/缓存/任务/邮件/监控

      导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 ...

  2. 11.3-全栈Java笔记:线程的生命周期

    一个线程对象在它的生命周期内,需要经历5个状态. 新生状态(New) 用new关键字建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态 ...

  3. java.util.concurrent.locks.Condition 源码

    2019独角兽企业重金招聘Python工程师标准>>> 相关类图: 使用Condition和 object作为条件队列的区别: object: 只能绑定一个内部队列,使用notify ...

  4. zbb20180929 thread java并发编程之Condition

    java并发编程之Condition 引言 在java中,对于任意一个java对象,它都拥有一组定义在java.lang.Object上监视器方法,包括wait(),wait(long timeout ...

  5. 10.4-全栈Java笔记:常用流详解(二)

    上节我们讲到「Java中常用流:文件字节流和字节数组流」,本节我们继续走起~  缓冲流 BufferedInputStream和BufferedOutputStream这两个流是处理流,通过内部缓存数 ...

  6. java笔记之抽象类和接口

    前言 java笔记之抽象类和接口是开发人员的设计工具 正文 1.抽象类 客观存在的一类事物,当这类事物都是抽象的,无法具体的描述. 1)语法: 修饰符 abstract class 类名{ } 2)特 ...

  7. 9.1-全栈Java笔记: 容器泛型—认识Collection接口

    开发和学习中需要时刻和数据打交道,如果组织这些数据是我们编程中重要的内容. 我们一般通过"容器"来容纳和管理数据.   事实上,数组就是一种容器,可以在其中放置对象或基本类型数据. ...

  8. java笔记(3):String(2)

    java笔记(3):String(2) 参考资料:网易云网课李兴华:http://study.163.com/course/courseMain.htm?courseId=1455026 一.字符串一 ...

  9. JAVA多线程-基础Lock Condition 并发集合

    代码的逻辑: 1)SProducer不停的产生number到queue中. 2)3个carrier不停的取出queue中的number. 3)如果queue中存在10个剩余number时,SProdu ...

最新文章

  1. 【实操】看了太多公式概念?你该学会怎么用T检验了!
  2. basequickadapter详解_BaseRecyclerViewAdapter(持续更新!)
  3. php自定义弹窗,自定义弹窗Style样式
  4. 对象容器设计模式_容器对象模式。 一种新的测试模式。
  5. 【计算机组成原理】数据存储的大端和小端
  6. 数组的去重-----------------------来自大牛的讲解
  7. Netty工作笔记0077---handler链调用机制实例4
  8. 如何避免循环中“突兀”的break和continue
  9. 目前看的GNN论文的一些总结
  10. logrotate 对某个日志的配置
  11. [JarvisOj][XMAN]lTell Me Something
  12. 黑马程序员传智播客 python生成器 学习笔记
  13. Android 学习博客
  14. rails 分页 Paging kaminari
  15. android provision apk 分析
  16. SQL每日一题 牛客17 10月的新客户单价和获客成本
  17. 牛批,Ceph RBD 备份与恢复完全指南
  18. ssi 指令 php,SSI使用详解(二)_PHP教程
  19. C++二维数组初始化的形式
  20. basler恢复出厂设置_实现图像实时采集(使用BaslerSDK)-C

热门文章

  1. 电脑与电脑之间数据是如何传输的(数据封装与解装)
  2. 玩转Linux文件描述符和重定向
  3. 潜伏研发群一个月,我发现了程序员不为人知的秘密!这也太可爱了吧
  4. 编程零基础做程序员,该怎么学习?首先要学习什么?
  5. 顽强奋斗的FreeEIM
  6. “XEIM”国内开源即时通讯XEIM
  7. 轻松实现 CTreeCtrl 的全选与反选
  8. 微软开放Xbox 360游戏开发平台
  9. 面向对象编程的五大基本原则
  10. 这份精子保存了1亿年,不仅长度惊人还刷新了一项记录