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();

	}
}