在上篇我们看到,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. 《java入门第一季》之UDP协议下的网络编程小案例

    需求,一台电脑发送数据,其他电脑都可以收到该数据.使用广播地址. 发送端: import java.io.BufferedReader; import java.io.IOException; imp ...

  2. 读书笔记 - reword (重来)

    reword (重来) 虽然我是一个不是很喜欢看书的人,但是公认的是看书对提高个人的水平是很有帮助的. 而且我想,如果我要写一本书,我一定会经过多次校验.经过长时间思考确保无误后才会出版的.所以我想看 ...

  3. python的sys模块

    Sys模块函数之多,我只能选取自己认为比较实用的一些函数列在此处.借马云找员工的说法,"找最合适的而不是最天才的",这句话,我个人觉得在很多方面都能适应,学习也不在话下.Sys模块 ...

  4. Socket编程实践(5) --TCP粘包问题与解决

    TCP粘包问题 由于TCP协议是基于字节流且无边界的传输协议, 因此很有可能产生粘包问题, 问题描述如下 对于Host A 发送的M1与M2两个各10K的数据块, Host B 接收数据的方式不确定, ...

  5. OJ题:句子逆转

    将一个英文语句以单词为单位逆序排放.例如"I am a boy",逆序排放后为"boy a am I"所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含 ...

  6. css3动画从入门到精通

    什么是css3动画? 通过 CSS3,我们能够创建动画,这可以在许多网页中取代动画图片.Flash 动画以及 JavaScript. CSS3带来了圆角,半透明,阴影,渐变,多背景图等新的特征,轻松实 ...

  7. OC——第五天NSSArray /NSDicti…

    1.oc中常用的集合(容器)有: 1.NSArry 数组:2.NSDicitionary 字典:3.NSSet 集(不常用) 数组:NSArry 继承自NSObject ,不可变的数组,用于管理一系列 ...

  8. 9.4、Libgdx简单字符输入

    (官网:www.libgdx.cn) 如果应用需要输入一个字符,比如用户名和密码,可以通过简单的对话框实现. 在桌面中使用一个Swing对话框,提示用户输入字符. 在Android中将会打开一个标准的 ...

  9. git简介及使用方法

    一.git简介及安装1.git简介 Git 是用于 Linux 内核开发的版本控制工具.与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持, ...

  10. Android官方技术文档翻译——Gradle 插件用户指南(7)

    本文译自Android官方技术文档<Gradle Plugin User Guide>,原文地址:http://tools.android.com/tech-docs/new-build- ...