大纲:

  1. wait、notify、notifyAll
  2. Condition
  3. 生产消费者

一、wait、notify、notifyAll

  1. wait、notify、notifyAll是Object的本地final方法。
  2. 在一个线程中调用object.wait()可以使当先线程阻塞并交出锁(object)。
  3. 既然obj.wait操作会交出锁,那必然在synchronized(obj)代码块内,且2个obj为统一对象。
  4. 使用obj.notify()能够唤醒任意一个等待obj锁的线程,obj.notifyAll()能够唤醒所有等待obj锁的线程。同样notify操作也必须在synchronized(obj)代码块内。
  5. 线程等待是锁对象的方法而不是线程的方法,试想在多个synchronized嵌套代码块内,调用wait()是不是应该指定释放哪一个锁对象。

二、Condition

  1. Condition接口依赖于Lock接口,可以通过lock.newCondition() 。
  2. wait,notify操作都是控制一个锁下面的线程。Condition可以将一个锁下面的线程分成多种情况分别控制。
  3. 调用Condition的await()和signal()方法也需要在lock()-unlock()代码块内。
  4. Condition接口的await对应Object的wait方法 ,signal对应notify方法 ,signalAll对应notifyAll方法 。
  5. 使用Condition也更加高效。
  6. void awaitUninterruptibly():不响应中断的await方法。
  7. 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多线程-线程间协作的更多相关文章

  1. Java并发--线程间协作的两种方式:wait、notify、notifyAll和Condition

    在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界 ...

  2. Java多线程——线程间通信

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...

  3. Java多线程之线程的状态以及线程间协作通信导致的线程状态转换

      转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html  一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...

  4. java并发编程 线程间协作

    线程间协作 1. 等待和通知 等待和通知的标准形式 等待方: 获取对象锁 循环中判断条件是否满足,不调用wait()方法 条件满足执行业务逻辑 通知方: 获取对象所 改变条件 通知所有等待在对象的线程 ...

  5. Java中详述线程间协作

    线程协作 首先引入一段代码: package 线程间数据共享; import java.util.Date; public class Watch { private static String ti ...

  6. Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  7. Java并发编程(十三)线程间协作的两种方式:wait、notify、notifyAll和Condition

    在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果 ...

  8. 多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  9. Java并发编程(九)线程间协作(下)

    上篇我们讲了使用wait()和notify()使线程间实现合作,这种方式很直接也很灵活,但是使用之前需要获取对象的锁,notify()调用的次数如果小于等待线程的数量就会导致有的线程会一直等待下去.这 ...

随机推荐

  1. mysql:unknown variable 'default -collation=utf8_general_ci'

    无法登陆,因为在配置文档中设置了默认编码方式 将它注释掉,问题就解决了 在utf8_bin中你就找不到 txt = 'A' 的那一行, 而 utf8_general_ci 则可以.utf8_gener ...

  2. ContextLoaderListener和Spring MVC中的DispatcherServlet学习 随手记

    Servlet上下文关系 DispatcherServlet的上下文是通过配置servlet的contextConfigLocation来加载的,默认实现是XmlWebApplicationConte ...

  3. Type Hierarchy

    Window - Preferences - General - Keys Name:         Open Type Hierarchy Description: Open a type hie ...

  4. APUE(5)---标准I/O库 (1)

    一.引言 标准I/O库不仅是UNIX,许多i其他操作系统都实现了标准I/O库,所以这个库由ISO C标准说明.标准I/O库处理很多细节,如缓冲区分配,以及优化的块长度执行I/O等.这使得它便于用户使用 ...

  5. kafka的api操作(官网http://kafka.apache.org/documentation/#producerapi)

    Kafka API 简单用法 本篇会用到以下依赖:(本人包和这个不同,去maven里查找) <dependency><groupId>org.apache.kafka</ ...

  6. Hadoop的Windows伪分布式学习

    解压hadoop-2.7.2.zip,不是tar.gz,前者是Windows所用的 解压到路径,设置环境变量 HADOOP_HOME=E:\hadoop-2.7.2\ HADOOP_USER_HOME ...

  7. BZOJ 2460 [BeiJing2011]元素(线性基模板题)

    Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石.一般地,矿石越多则法力越强 ...

  8. nginx+tomcat实现动静态分离

    ===============Tomcat 概述: Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache ...

  9. CentOS 7安装GitLab、汉化、配置邮件发送

    1.更换国内yum源 1.1 备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 1.2 ...

  10. HTTP 常见异常状态及Delphi IDHTTP 控件处理方式

    以下部分为网上查找,部分为工作中整理 200:请求成功 202:请求被接受,但处理尚未完成 302:请求到的资源在一个不同的URL处临时保存     处理方式:重定向到临时的URL(IDHTTP处理方 ...