java多线程-线程间协作
大纲:
- wait、notify、notifyAll
- Condition
- 生产消费者
一、wait、notify、notifyAll
- wait、notify、notifyAll是Object的本地final方法。
- 在一个线程中调用object.wait()可以使当先线程阻塞并交出锁(object)。
- 既然obj.wait操作会交出锁,那必然在synchronized(obj)代码块内,且2个obj为统一对象。
- 使用obj.notify()能够唤醒任意一个等待obj锁的线程,obj.notifyAll()能够唤醒所有等待obj锁的线程。同样notify操作也必须在synchronized(obj)代码块内。
- 线程等待是锁对象的方法而不是线程的方法,试想在多个synchronized嵌套代码块内,调用wait()是不是应该指定释放哪一个锁对象。
二、Condition
- Condition接口依赖于Lock接口,可以通过lock.newCondition() 。
- wait,notify操作都是控制一个锁下面的线程。Condition可以将一个锁下面的线程分成多种情况分别控制。
- 调用Condition的await()和signal()方法也需要在lock()-unlock()代码块内。
- Condition接口的await对应Object的wait方法 ,signal对应notify方法 ,signalAll对应notifyAll方法 。
- 使用Condition也更加高效。
- void awaitUninterruptibly():不响应中断的await方法。
- long awaitNanos(long nanosTimeout) throws InterruptedException:await上增加超时响应,返回值=nanosTimeout-消耗时间。
三、生产消费者
生产者、消费者线程轮流执行,操作同一个资源。
消费者:
public class Comsumer implements Runnable {
Resource resource;
public Comsumer(Resource resource){
this.resource = resource;
}
@Override
public void run() {
try {
resource.comsume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
生产者:
public class Producer implements Runnable {
Resource resource;
public Producer(Resource resource){
this.resource = resource;
}
@Override
public void run() {
try {
resource.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
资源对象-wait,notify实现:
public class Resource { private int r = 0;
private Object lock = new Object();
private boolean produced = false; public void produce() throws InterruptedException {
synchronized(lock){
while (true){
while (produced){
lock.wait();
}
r++;
System.out.println(Thread.currentThread().getName()+"线程成产1个,当前剩余:"+r);
produced = true;
lock.notifyAll();
}
} } public void comsume() throws InterruptedException {
synchronized(lock){
while (true){
while (!produced){
lock.wait();
}
r--;
System.out.println(Thread.currentThread().getName()+"线程消费1个,当前剩余:>>"+r);
produced = false;
lock.notifyAll();
}
} }
}
资源对象-condition实现:
public class Resource { private int r = 0;
private boolean produced = false;
Lock lock = new ReentrantLock();
Condition proCondition = lock.newCondition();
Condition comCondition = lock.newCondition(); public void produce() throws InterruptedException {
lock.lock();
try {
while (true){
while (produced){
proCondition.await();
}
r++;
System.out.println(Thread.currentThread().getName()+"线程成产1个,当前剩余:"+r);
produced = true;
comCondition.signal();
}
}finally {
lock.unlock();
} } public void comsume() throws InterruptedException {
lock.lock();
try {
while (true){
while (!produced){
comCondition.await();
}
r--;
System.out.println(Thread.currentThread().getName()+"线程消费1个,当前剩余:>>"+r);
produced = false;
proCondition.signal();
}
}finally {
lock.unlock();
} }
}
测试类
class TestWait {
public static void main(String[] args) {
Resource r = new Resource();
Producer producer = new Producer(r);
Comsumer comsumer = new Comsumer(r);
new Thread(producer).start();
new Thread(producer).start();
new Thread(producer).start();
new Thread(comsumer).start();
new Thread(comsumer).start();
new Thread(comsumer).start();
}
}
java多线程-线程间协作的更多相关文章
- Java并发--线程间协作的两种方式:wait、notify、notifyAll和Condition
在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界 ...
- Java多线程——线程间通信
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- Java多线程之线程的状态以及线程间协作通信导致的线程状态转换
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html 一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...
- java并发编程 线程间协作
线程间协作 1. 等待和通知 等待和通知的标准形式 等待方: 获取对象锁 循环中判断条件是否满足,不调用wait()方法 条件满足执行业务逻辑 通知方: 获取对象所 改变条件 通知所有等待在对象的线程 ...
- Java中详述线程间协作
线程协作 首先引入一段代码: package 线程间数据共享; import java.util.Date; public class Watch { private static String ti ...
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程(十三)线程间协作的两种方式:wait、notify、notifyAll和Condition
在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果 ...
- 多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程(九)线程间协作(下)
上篇我们讲了使用wait()和notify()使线程间实现合作,这种方式很直接也很灵活,但是使用之前需要获取对象的锁,notify()调用的次数如果小于等待线程的数量就会导致有的线程会一直等待下去.这 ...
随机推荐
- 网站配置新的YII2可运行版本
1. config 中的 gitignore 先将 -local 加入版本库 2. 将 runtime 目录添加写权限 3. 将web目录的asset 添加写的权限 4.
- jQuary总结9:html()的常见用法
1html() 不传参数 用于获取内容 //html <div> <p></p> <span></span> 文本 </div> ...
- 公司web安全等级提升
目录 背景介绍 目录 针对国调的初次测试结果 解决方案 二次测试 关于XSS 什么是XSS 基本防御 代码防御 xss代码辑录 说明 参考文章 版本记录 背景介绍 公司的一个web数据展示系统,本来是 ...
- Statement 接口的应用(存在sql语句的注入风险)
实现简单的登录功能 import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; impo ...
- XJOI 3605 考完吃糖(DAG图dfs)
题目描述: 期末考试考完了,分数也出来了,大家准备吃糖庆祝一下,为了鼓励同学们下学期能取得更好的成绩,司马红豆同学让n个同学站成一排,如果某个同学的分数比相邻的一个同学要高,那么他得到的糖果就会比这个 ...
- 再次理解js中的call函数
a.call(b); 网上说明的版本比较多.有的说,是指针替换.有说,将a对象的方法加在b对象执行.官方说:什么对象替换什么对象.反正看了几个版本,尽管有具体的实例,看了我三次都没看懂它的具体含义.看 ...
- ubuntun16.0 登陆密码忘记
1. 开机,如下图所示(没有装虚拟机,手机拍的图片凑合这看把): 2. 此时会有一个选项:Advanced Options for Ubuntu, 选中直接回车 ,如下图: 3. 看到里面有很多选项, ...
- PopupWindow封装
代码完全复制:https://github.com/pinguo-zhouwei/CustomPopwindow 使用参考:上面的github地址 1.封装类 /** * * 自定义PopWindow ...
- Visual Studio 2008 SP1键盘F10单步调试超慢解决方法
症状: 中断程序调试时,F10或者其它键盘操作都超级慢. 鼠标点击工具栏的按钮速度正常. 解决方法: 网上说的什么删掉所有断点啦,关掉几个窗口啦,重置用户设置啦,关掉某某调试选项啦,关掉防火墙啦,都是 ...
- HAOI2010 工厂选址
题目链接:戳我 数组开小火葬场qwqwq 就是一个贪心吧.对于一个数,我们知道只有两种摆放方式.所以我们可以先都放到新的里面,然后做一下新的-原先的差,按照差从大到小排序,依次提取数值减去即可. 代码 ...