1.wait和notify,notifyAll

  • wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中。
  • wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中。wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方法或者notifyAll方法后,才能唤醒线程池中等待的线程。
  • notify()方法:唤醒线程池中的任意一个线程。
  • notifyAll方法:唤醒线程池中的所有线程。

2.线程间通信:多个线程操作同一个资源,但是操作的动作不同,任务不同。

3.等待唤醒机制:操作共享数据的不同动作,一个存入,一个取出;当输入一个的时候,另一个要取出。先让输入线程等待,等输出线程取出后,再唤醒输入线程。

下面看一个例子:需求是要求两个线程操作Resource资源类中的成员变量name,sex,要求一个线程往共享资源类中存入一个姓名和一个姓别,即存入一个资源对象,另一个线程就取出资源类中的对象。即存入一个,就要取出,资源类中对象为空的时候,就再存入一个。这个例子可以用等待唤醒机制解决。

思路:这里在线程代码里面设计一个姓名为peter,性别为man;另一个姓名为“李明”,性别为“男”。通过模2进行切换。输入线程选择操作这连个对象。

class Res{
String name;
String sex;
boolean flag = false;
} class Input implements Runnable{
Object obj = new Object();
private Res r ; public Input(Res r){//通过构造方法初始化资源,把Res传递进来,一构造对象,资源被初始化
this.r = r;
} public void run(){
int x= 0;
while(true){
synchronized(r){//同步代码块,锁为r
if(r.flag){//如果资源里面有一个姓名和名字了,input线程就冻结,释放执行权,释放执行资格,释放锁
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(x == 0){//切换x,通过模2进行切换
r.name="peter";
r.sex="man";
}else{
r.name="李明";
r.sex="男男男男";
}
x = (x+1)%2;//取模运算,模2=0,取名字为Mike,性别为man,不等于0,则取小红,女女女女
r.flag = true;//当存入一个,标志变为true,输入线程进入等待,处于冻结状态,等待输出线程输出
r.notify();//唤醒线程池中的其它线程,唤醒第一个等待的输出线程
}
}
} }
class OutPut implements Runnable{
Object obj = new Object();
private Res r;
public OutPut(Res r){
this.r = r;
}
public void run() { while(true){
synchronized(r){
if(!r.flag)
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//如果r.flag=true,说明资源Res里面有一个东西,输出里面名字和性别
System.out.println(r.name+ "......"+r.sex);
r.flag=false;//当输出一个,标志改为false,这时输出线程进入线程池进行等待,直到被唤醒
r.notify();//唤醒输入线程,导致当前线程等待
}
}
} }
public class ThreadorThreadSpeak { /**
* @param args
*/
public static void main(String[] args) {
//创建资源
Res r = new Res();//比喻为煤资源
//创建任务
Input in = new Input(r);
OutPut out = new OutPut(r);
//创建线程
Thread t1 = new Thread(in);//输入线程
Thread t2 = new Thread(out);//输出线程
//开启线程
t1.start();
t2.start();
} }

优化上面的代码,把同步代码块中的代码封装成同步函数

class Resource
{
private String name;
private String sex;
private boolean flag = false; public synchronized void set(String name,String sex)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
} public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(name+"...+...."+sex);
flag = false;
notify();
}
} //输入
class Input implements Runnable
{
Resource r ;
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
       //取2模进行切换
if(x==0)
{
r.set("peter","nan");
}
else
{
r.set("李明","男男男男");
}
x = (x+1)%2;
}
}
}
//输出
class Output implements Runnable
{ Resource r;
Output(Resource r)
{
this.r = r;
} public void run()
{
while(true)
{
r.out();
}
}
} class ResourceDemo3
{
public static void main(String[] args)
{
//创建资源。
Resource r = new Resource();
//创建任务。
Input in = new Input(r);
Output out = new Output(r);
//创建线程,执行路径。
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
//开启线程
t1.start();
t2.start();
}
}

输出:

peter......man
李明......男男男男
peter......man
李明......男男男男
peter......man

 

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)的更多相关文章

  1. java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

     *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...

  2. java基础知识回顾之---java String final类普通方法

    辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      ...

  3. Java基础知识回顾之七 ----- 总结篇

    前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...

  4. Java基础-进程与线程之Thread类详解

    Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...

  5. java 22 - 17 多线程之等待唤醒机制(接16)

    先来一张图,看看什么叫做等待唤醒机制 接上一章的例子. 例子:学生信息的录入和获取 * 资源类:Student  * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread( ...

  6. Java基础知识回顾(一):字符串小结

    Java的基础知识回顾之字符串 一.引言 很多人喜欢在前面加入赘述,事实上去技术网站找相关的内容的一般都应当已经对相应知识有一定了解,因此我不再过多赘述字符串到底是什么东西,在官网中已经写得很明确了, ...

  7. Java 之多线程通信(等待/唤醒)

    多线程间通信: 多个线程在处理同一个资源, 但是任务却不同. 等待/唤醒机制 涉及的方法 wait(): 让线程处于冻结状态, 被 wait() 的线程会被存储到线程池中 notify(): 唤醒线程 ...

  8. Java第二十五天,多线程之等待唤醒机制

    当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态: 这六种状态之间的转换关系如下: 1.等待唤醒机制 注意: (1)两个线程之间必须用同步代码块 ...

  9. java基础知识回顾之java Thread类学习(三)--java线程实现常见的两种方式实现好处:

    总结:实现Runnable接口比继承Thread类更有优势: 1.因为java只能单继承,实现Runnable接口可以避免单继承的局限性 2.继承Thread类,多个线程不能处理或者共享同一个资源,但 ...

随机推荐

  1. [NOIP2014]解方程

    3732 解方程  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 输入描述 Input Descrip ...

  2. linux 线程函数大全

    Technorati 标签: Linux thread 索引: 1.创建线程pthread_create 2.等待线程结束pthread_join 3.分离线程pthread_detach 4.创建线 ...

  3. 素数个数统计——Eratosthenes筛法 [LeetCode 204]

    1- 问题描述 Count the number of prime numbers less than a non-negative number, n 2- 算法思想 给出要筛数值的范围 $n$,找 ...

  4. windows phone 8 开发系列(一)环境搭建

    一:前奏说明 本人一名普通的neter,对新玩意有点小兴趣,之前wp7出来的时候,折腾学习过点wp7开发,后来也没怎么用到(主要对微软抛弃wp7的行为比较不爽),现在wp8已经出来一段时间了,市场上也 ...

  5. Spring.Net的Ioc功能基本配置

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入.面向方面编程(AOP).数据访问抽象及ASP.NET扩展等等. Spri ...

  6. Berkeley DB数据处理

    设计一个结构,利用Berkeley DB完成大数据的存储,备份,查询功能. 已有的储备: 1.Berkeley DB的基本操作. 2.数据转存后数据不丢失. 3.过百GB以上数据的存储. 数据流如下, ...

  7. JavaScript 垃圾回收机制分析

    同C# .Java一样可以手工调用垃圾回收程序,但是由于其消耗大量资源,而且手工调用的不会比浏览器判断的准确,所以不推荐手工调用垃圾回收.   最近精力主要用在了Web 开发上,读了一下<Jav ...

  8. 微软更换考试中心后报名攻略以及MCT半价

    微软从Prometric更换为Pearson的考试中心,比起以前的预约流程更加便捷. Pearson VUE为微软公司提供MCP考试服务 Pearson VUE为微软公司提供MCP考试服务 http: ...

  9. C# 命名参数【转】

    命名参数(Named Arguments)就是说在调用函数时可以通过指定参数名称的方式来调用参数.它最大的好处就是方便调用参数时按调用者的需要来排列顺序,而不必死守函数声明时的顺序(相对于“位置参数” ...

  10. oracle 11g rac 修改字符集

    系统版本: Oracle Linux Server release 5.7 数据库版本: Oracle Database 11g Enterprise Edition Release 11.2.0.3 ...