在上篇我们看到,A线程往公共资源库(对象)提供了一条数据,然后B线程从库中提取了数据并打印出来。

实际项目中,我们不可能只往库中提供一条数据,而且库的大小也不会是无穷大的,那么我们就会有这样一

个需求:A线程提供了一定的数据量后就暂停,等待B线程全部取走之后(因为B再不来取的话,库就装不下

了),A线程再往其中添加数据,如此往复。这里存在两种方法;

1.资源库对象的wait()方法和notify()方法/notifyAll()方法

 public class Share {
String name;
String sex;
//用empty来表示库中是否有数据
boolean empty = true; // 线程A的任务,提供数据
synchronized public void product(String name, String sex) {
try {
while(!empty) {
//当库中数据不为空时,A线程不能向其添加数据,小憩一会儿
this.wait();
}
//当库中数据为空时,A线程向其添加数据
this.name = name;
this.sex = sex;
//添加完成之后,更改库中数据状态为不空,并唤醒其他线程来拿数据
empty=false;
this.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
} } // 线程B的任务,提取(显示)数据
synchronized public void show() {
try {
while(empty) {
//当库中数据为空时,B线程不能获取数据,小憩一会儿
this.wait();
}
//当库中数据不为空时,B线程获取数据并打印
System.out.println("姓名:" + this.name + "性别:" + this.sex);
//拿完数据之后,更改库中数据状态为空,并唤醒其他线程继续写数据
empty=true;
this.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

wait()方法和notifyAll()方法只能由同步监听器对象来调用,就是这里说的资源库对象。

2.同步锁(Lock)和Condition接口

之前讲线程同步时有说到同步锁的方法,这种方法是没有同步监听器对象的,那么上面的wait()等方法就不能用了,

但是不用担心,java5在推出同步锁的时候也为其通信控制提供了一个方法获得Condition对象,来实现通信控制

 public class Share {
String name;
String sex;
//创建锁
final Lock lock = new ReentrantLock();
//创建Condition对象
Condition condition = lock.newCondition();
// 用empty来表示库中是否有数据
boolean empty = true; // 线程A的任务,提供数据
public void product(String name, String sex) {
lock.lock();//上锁
try {
while (!empty) {
// 当库中数据不为空时,A线程不能向其添加数据,小憩一会儿
condition.await();
}
// 当库中数据为空时,A线程向其添加数据
this.name = name;
this.sex = sex;
// 添加完成之后,更改库中数据状态为不空,并唤醒其他线程来拿数据
empty = false;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();//解锁
} // 线程B的任务,提取(显示)数据
public void show() {
lock.lock();//上锁
try {
while (empty) {
// 当库中数据为空时,B线程不能获取数据,小憩一会儿
condition.await();
}
// 当库中数据不为空时,B线程获取数据并打印
System.out.println("姓名:" + this.name + "性别:" + this.sex);
// 拿完数据之后,更改库中数据状态为空,并唤醒其他线程继续写数据
empty = true;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
condition.signalAll();//解锁
}
}

java线程之线程通信控制的更多相关文章

  1. Java多线程 2 线程的生命周期和状态控制

    一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...

  2. java 多线程 4 线程池

    系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似 ...

  3. Java并发1——线程创建、启动、生命周期与线程控制

    内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...

  4. (转)java自带线程池和队列详细讲解 - CSDN过天的专栏

    一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util ...

  5. 线程和线程池的理解与java简单例子

    1.线程 (1)理解,线程是系统分配处理器时间资源的基本单元也是系统调用的基本单位,简单理解就是一个或多个线程组成了一个进程,进程就像爸爸,线程就像儿子,有时候爸爸一个人干不了活就生了几个儿子干活,会 ...

  6. 小谈Java里的线程

    今天,我们来谈一谈Java里的线程. 一.进程与线程的基本概念 大家可能没听过线程这个概念,但是相信,用计算机的朋友都听过进程这个概念.打开电脑的任务管理器,我们就可以看到许多进程.它们主要分为三类, ...

  7. Java 多线程 自定义线程辅助

    之前的文章我介绍了C#版本的多线程和自定义线程处理器. 接下来我们来看看Java版本的呢 java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的 ...

  8. Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  9. 【转】关于Java的Daemon线程的理解

    原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.html 关于Java的Daemon线程的理解 网上对Java的Dae ...

  10. 第24章 java线程(3)-线程的生命周期

    java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...

随机推荐

  1. android 解析服务器数据使用json还是xml方式

    整理自百度搜索: 现在的Android应用程序,几乎没有不与服务端交换数据的了!那么,android应用在与服务端交换数据的时候,我们有哪些选择呢?哪种数据交换格式要更好吗?下面文章简单为 andro ...

  2. 使用go reflect实现一套简易的rpc框架

    go jsonrpc 在实际项目中,我们经常会碰到服务之间交互的情况,如何方便的与远端服务进行交互,就是一个需要我们考虑的问题. 通常,我们可以采用restful的编程方式,各个服务提供相应的web接 ...

  3. 关于MySQL insert into ... select 的锁情况

    摘要:       一直以为"insert into tb select * from tbx" 这样的导入操作是会把tbx表给锁住的,在锁期间是不允许任何操作(保证一致性).看完 ...

  4. HEVC,VP9,x264性能对比

    Dan Grois等人在论文<Performance Comparison of H.265/MPEG-HEVC, VP9, andH.264/MPEG-AVC Encoders>中,比较 ...

  5. 数据结构基础(21) --DFS与BFS

    DFS 从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到(使用堆栈). //使用邻接矩阵存储的无向图的深度 ...

  6. Cygwin获取root权限

    .启动cygwin进入以后,就会以真正的root权限运行了.

  7. iOS基础常用细节问题处理65条

    1. 不可变数组  转变为可变数组  //声明实例变量的数组  必须记得实现 //对于遍历数组找到对象后 如果还需要查找 记得先结束 再查找(return/break) NSArray * arr = ...

  8. JavaScript进阶(七)JS截取字符串substr 和 substring方法的区别

    JS截取字符串substr 和 substring方法的区别 substr方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参 ...

  9. XML 处理利器 : XStream

    XStream 概述      XStream 是一套简洁易用的开发类库,用于将Java对象序列化为XML或者将XML反序列化为JAVA对象,是JAVA对象和XML之间一个双向转换器. 举例     ...

  10. iOS中NSBundle的介绍

    bundle是一个目录,其中包含了程序会使用到的资源.这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in).对应bundle,cocoa提供了类NSBund ...