Java线程的等待/唤醒机制实例演示
package demo;
/*
* 线程间通讯;
* 多个线程处理同意资源,但是任务却不同
* */
/*
* 等待/唤醒机制
* 涉及的方法:
* 1·wait():让线程处于冻结状态,被wait的线程会被存储到线程池(容器)中
* 2·notify():唤醒线程池中的一个线程(任意)
* 3·notifyAll():唤醒线程池中的所有线程
* 这些方法都必须定义在同步中,因为这些方法时用于操作线程状态的方法,必须要明确
* 到底要操作的是哪个锁上的线程
* */
//为什么操作线程的方法wait(),notify(),notifyAll()定义在Object类中?
//因为这些方法是监视器的方法。监视器其实就是锁。锁可以是任意的对象,
//任意的对象调用的方法一定定义在Object类中
//资源类
class Resource
{
String name;
String sex;
boolean flag = false;
}
//输入类
class Input implements Runnable
{
Resource r;
public Input(Resource r)
{
// TODO Auto-generated constructor stub
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
int x = 0;
while(true)
{
synchronized (r)
{
if(r.flag)
try
{
r.wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if(x==0)
{
r.name = "mike";
r.sex = "nan";
}
else
{
r.name = "涵涵";
r.sex = "女生";
}
r.flag = true;
r.notify();
}
x = (x+1)%2;
}
}
}
//输出类
class Output implements Runnable
{
Resource r;
public Output(Resource r)
{
// TODO Auto-generated constructor stub
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
{
synchronized (r)
{
if(!r.flag)
try
{
r.wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(r.name+"..."+r.sex);
r.flag = false;
r.notify();
}
}
}
}
public class ResourceDemo
{
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();
}
}
###优化之后的代码
package demoUpgraded;
/*
* 线程间通讯;
* 多个线程处理同意资源,但是任务却不同
* */
/*
* 等待/唤醒机制
* 涉及的方法:
* 1·wait():让线程处于冻结状态,被wait的线程会被存储到线程池(容器)中
* 2·notify():唤醒线程池中的一个线程(任意)
* 3·notifyAll():唤醒线程池中的所有线程
* 这些方法都必须定义在同步中,因为这些方法时用于操作线程状态的方法,必须要明确
* 到底要操作的是哪个锁上的线程
* */
//为什么操作线程的方法wait(),notify(),notifyAll()定义在Object类中?
//因为这些方法是监视器的方法。监视器其实就是锁。锁可以是任意的对象,
//任意的对象调用的方法一定定义在Object类中
//资源类
class Resource
{
//为提高代码的安全性将成员变量私有化
private String name;
private String sex;
private boolean flag = false;
/*
* 因为成员变量已被私有化,故需要向外提供使用成员变量的接口,将操作封装起来
* 设置姓名和性别
* 将标志位改为true,经过判断则输入线程将处于等待状态
* 同时唤醒输出线程
* */
public synchronized void in(String name,String sex)
{
if(this.flag)
try
{
this.wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.sex = sex;
flag = true;
notify();
}
/*
* 同输入线程一样,提供向外操作成员变量的接口
* 若标志位flag为false则输出线程进入等待状态,等待输入线程的notify唤醒
* 若标志位flag为true则输出姓名和性别
* 同时将标志位flag置为false
* 唤醒输入线程
* */
public synchronized void out()
{
if(!this.flag)
try
{
this.wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+"..."+sex);
flag = false;
notify();
}
}
//输入类
class Input implements Runnable
{
Resource r;
public Input(Resource r)
{
// TODO Auto-generated constructor stub
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
int x = 0;
while(true)
{
if(x==0)
{
r.in("mike","nan");
}
else
{
r.in("米粒儿","女生");
}
x = (x+1)%2;
}
}
}
//输出类
class Output implements Runnable
{
Resource r;
public Output(Resource r)
{
// TODO Auto-generated constructor stub
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
{
r.out();
}
}
}
public class UpgradedResourceDemo
{
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();
}
}