java线程之线程通信控制
在上篇我们看到,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线程之线程通信控制的更多相关文章
- Java多线程 2 线程的生命周期和状态控制
一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...
- java 多线程 4 线程池
系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似 ...
- Java并发1——线程创建、启动、生命周期与线程控制
内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...
- (转)java自带线程池和队列详细讲解 - CSDN过天的专栏
一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util ...
- 线程和线程池的理解与java简单例子
1.线程 (1)理解,线程是系统分配处理器时间资源的基本单元也是系统调用的基本单位,简单理解就是一个或多个线程组成了一个进程,进程就像爸爸,线程就像儿子,有时候爸爸一个人干不了活就生了几个儿子干活,会 ...
- 小谈Java里的线程
今天,我们来谈一谈Java里的线程. 一.进程与线程的基本概念 大家可能没听过线程这个概念,但是相信,用计算机的朋友都听过进程这个概念.打开电脑的任务管理器,我们就可以看到许多进程.它们主要分为三类, ...
- Java 多线程 自定义线程辅助
之前的文章我介绍了C#版本的多线程和自定义线程处理器. 接下来我们来看看Java版本的呢 java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的 ...
- Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- 【转】关于Java的Daemon线程的理解
原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.html 关于Java的Daemon线程的理解 网上对Java的Dae ...
- 第24章 java线程(3)-线程的生命周期
java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...
随机推荐
- www-authenticate与BASE-64认证技术
www-authenticate是一种简单的用户身份认证技术.很多验证都采用这种验证方式,尤其在嵌入式领域中.优点:方便缺点:这种认证方式在传输过程中采用的用户名密码加密方式为BASE-64,其解码过 ...
- 深入理解android6.0 RunTime Permisstion
了解下runtime permission 2015.8 google发布了android 6.0,sdk版本为23,一款"为工作升级而生"的android系统.如6.0新加入的指 ...
- Android studio中的一次编译报错’Error:Execution failed for task ':app:transformClassesWithDexForDebug‘,困扰了两天
先说下背景:随着各种第三方框架的使用,studio在编译打包成apk时,在dex如果发现有相同的jar包,不能创建dalvik虚拟机.一个apk,就是一个运行在linux上的一个虚拟机. 上图就是一直 ...
- Linux Debugging(五): coredump 分析入门
作为工作几年的老程序猿,肯定会遇到coredump,log severity设置的比较高,导致可用的log无法分析问题所在. 更悲剧的是,这个问题不好复现!所以现在你手头唯一的线索就是这个程序的尸体: ...
- java Serializable 生成随机序列
如果你implements 了 Serializable接口 但是没写 UID,eclipse会在你的类名边上有一个警告,你点击一下,有一个选项自动生成 UID,所以请用eclipse写java代码
- UIView、UIViewLayout UI_01
1.首先:在UI里面我们使用的是MRC,需要把ARC改成NO: 若学习比较吃力,可以先学习一下基础: http://blog.sina.com.cn/s/blog_814ecfa90102vuzg.h ...
- Java序列化Serializable和Externalizable
纸上得来终觉浅,绝知此事要躬行 --陆游 问渠那得清如许,为有源头活水来 --朱熹 什么是Java序列化?为什么出现Java序列化?怎样实现Java序列化? 一.什么是Java序列化 ...
- 理解WebKit和Chromium: Chromium插件和扩展基础
转载请注明原文地址:http://blog.csdn.net/milado_nju ##概述 插件和扩展是一种扩充浏览器功能的技术,在之前我们介绍过NPAPI插件技术,在Chromium中,远远不只是 ...
- 断言(Assertion)需要注意的一个地方
因为断言只在debug构建中有效,所以它是中关重要的去避免运行任何代码或调用任何方法在断言条件中,而这些代码或方法会影响程序的状态. 否则程序的行为将在debug和release构建中变得不一致,这显 ...
- 纯命令提交代码到git仓库(教你怎么装逼)
如果不喜欢用命令的请点链接:http://blog.csdn.net/xiangzhihong8/article/details/50715427 我这里用纯命令,主要是因为这两天不知道什么原因,ba ...