java并发编程:自定义同步工具
来源:互联网 发布:龙珠直播软件 编辑:程序博客网 时间:2024/06/05 22:37
条件谓词
在进行某些操作之前,需要进行一些先置条件判断。例如阻塞队列BlockingQueue在进行put操作之前,要先判断队列是否已满,如果已满,就会阻塞,直到队列空出位置出来,才能释放出来,继续执行操作。其中,“队列是否已满”就是条件谓词。
条件队列
在操作不满足条件谓词时,就会被阻塞,该线程就会被塞入对应锁的等待队列中,这个队列即为条件队列。
使用notify的危害
队列中如果有多种条件谓词,可能出现当条件谓词A满足条件后,打算唤醒线程A,但是由于notify的随机唤醒机制,却唤醒了条件谓词为B的线程B,导致线程A一直等不到唤醒信号,线程B被唤醒了,但是它的条件谓词却不为真。
使用notify的优点
notify比notifyAll高效。notifyAll是把所有等待的线程全部唤醒,这些线程会发生竞争,等到其中一个线程获取到锁之后,其它大部分线程就又会回到休眠状态。这过程中,将会出现大量的线程竞争和线程上下文切换。
使用notify的条件
- 条件队列中,只有一种条件谓词
- 条件队列为单进单出队列
信号丢失问题
- 使用notify可能引起信号丢失
- 条件谓词为真,线程被唤醒之后,条件谓词却又被其它线程修改为假了
信号丢失问题解决办法
- 尽量不使用notify,要使用的话,一定要满足上述使用notify的所有条件
- 在线程被唤醒之后,对条件谓词进行再次判断,如果不为真,则继续等待
使用object自带的方法创建同步工具
我们这里用object自带的方法来实现阻塞队列。
public class BlockingQueueUseObject { private Object[] array = new Object[10]; private int count = 0; public synchronized void put(Object obj) throws InterruptedException { while (count == array.length) { this.wait(); } array[count] = obj; count++; if (count == 1) { this.notifyAll(); } } public synchronized Object take() throws InterruptedException { while (count == 0) { this.wait(); } count--; if (count == array.length - 1) { this.notifyAll(); } return array[count]; }}
使用显示的Condition对象
import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantLock;public class BlockingQueueUseObject { private ReentrantLock lock = new ReentrantLock(); private Condition notFull = lock.newCondition(); private Condition notEmpty = lock.newCondition(); private Object[] array = new Object[10]; private int count = 0; public synchronized void put(Object obj) throws InterruptedException { lock.lock(); try { while (count == array.length) { notFull.await(); } array[count] = obj; count++; if (count == 1) { notEmpty.signal(); } } finally { lock.unlock(); } } public synchronized Object take() throws InterruptedException { lock.lock(); try { while (count == 0) { notEmpty.await(); } count--; if (count == array.length - 1) { notFull.signal(); } return array[count]; } finally { lock.unlock(); } }}
使用Condition的优点
每个条件队列都与锁绑定,JVM内置锁只能绑定一个条件队列,如果有多个条件谓词的时候,只能使用notifyAll,比较低效。而显示锁ReentrantLock可以创建多个Condition,每个Condition自带一个条件队列,能够使用比较高效的signal。
阅读全文
1 0
- java并发编程:自定义同步工具
- Java多线程并发编程之构建自定义同步工具
- java并发编程实战-构建自定义的同步工具
- java并发编程--自定义同步组件
- Java并发编程(自定义同步组件)
- Java高并发编程:同步工具类
- java并发编程:同步工具类
- 《Java并发编程实战》第十四章 构建自定义的同步工具 读书笔记
- java并发编程实践学习(14 ) 构建自定义的同步工具
- Java并发编程实战(学习笔记 十三 第十四章 构建自定义的同步工具 上)
- Java并发编程实战(学习笔记 十三 第十四章 构建自定义的同步工具 下 )
- java并发编程(四)同步工具类
- Java 并发编程(四)常用同步工具类
- JAVA 并发编程-线程同步工具类(十二)
- Java并发编程类学习五(同步工具)
- 【5】Java并发编程:线程同步工具之CountDownLatch类
- JAVA 并发编程-线程同步工具类(十二)
- Java并发之同步工具
- JVM初探- 使用堆外内存减少Full GC
- JVM调优总结(四)-垃圾回收面临的问题
- HTML5新增的全局属性
- 安装Redis
- 流式布局FlowLayout的动态添加删除
- java并发编程:自定义同步工具
- dubbo 的安装和使用
- mycat中间件(五)mycat配置文件之schema.xml 第一部分
- 第六次C++作业
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践
- 写给迷茫的程序员
- vlayout源码思路解析
- 和文本框有关的练习(JTextArea和document)
- spring 加载自定义配置