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()调用的次数如果小于等待线程的数量就会导致有的线程会一直等待下去.这 ...
随机推荐
- Android开发adb环境配置
adb的全称为Android Debug Bridge,就是起到调试桥的作用. 在命令行cmd中打开adb,如果Android开发的环境配置有误,会出现如下错误提示: 解决方法,右键我的电脑-> ...
- Yii项目开发总结
学习Yii很久了,一直做的是小案例,自以为学的还不错.直到最近用Yii开发了一个非常简单的CMS,一路下来,磕磕绊绊,才知自己不足.加上最近正学习着偏架构方面的知识.特此总结一下.小白经验,大神轻拍, ...
- javascript总结44: DOM对象的dataset属性方式
1 DOM设置属性的特殊方式: DOM对象的dataset属性方式获取data-xxx方式定义的属性 由于我们经常需要在标签上自定义属性来存储数据或状态,但是如果用传统的方式操作起来比较繁琐,而且不熟 ...
- WordPaster-Joomla_3.4.7-tinymce 4.1.7示例发布
资源下载:Joomla 3x, 1.1.1. 1.添加wordpaster文件夹 /media/ 1.1.2. 2.添加插件文件夹 路径:media/editors/tinymce/plugi ...
- page next page prev
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- 设计模式13:Template Method 模板方法模式(行为型模式)
Template Method 模板方法模式(行为型模式) 变与不变 变化——是软件永恒的主题,如何管理变化带来的复杂性?设计模式的艺术性和复杂度就在于如何分析,并发现体系中的变化点和稳定点,并使用特 ...
- APUE(7)---进程环境
一.main函数 C程序总是从main函数开始执行.main函数的原型是: int main(int argv, char *argv[]); 当内核执行C程序时,在调用main前先调用一个特殊的启动 ...
- win7 64位备份时, 无法启动服务,0x80070422
问题:当win7 64位系统在备份的时候,无法启动备份服务,错误代码:0x80070422 解决方法:计算机->管理->服务 找到 Block Level Backup Engine Se ...
- [SIP01]SIP Header Fields里面各字段用途
INVITE sip:bob@biloxi.com SIP/2.0 Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds Max-Forw ...
- 格式化JavaScript代码
javascript代码格式化工具 网上下载的js代码经常遇到代码已被压缩(注释.换行.缩进.空格.TAB等都被删除了),如果拿来学习.研究的话必定看到头晕.有些编辑器的“格 式化代码”功能可以解决这 ...