Java笔记十六 等待唤醒机制

编辑器:Notepad++;学习视频:毕向东Java基础教程

一、线程间的通信

(1)wait(),notify(),notifyAll(),用来操作线程,为什么定义在了Object类中?

  • 这些方法存在于同步中
  • 使用这些方法时,必须标识所属的同步的锁
  • 锁可以是任意对象,任意对象调用的方法一定定义在Object类中

(2)wait()和sleep()有什么区别?

  • wait():释放CPU执行权,释放锁
  • sleep():释放CPU的执行权,不释放锁

(3)多个线程处理同一资源,但任务不同。

二、等待唤醒机制

(1)涉及的方法

  • wait(): 使线程处于冻结状态,被wait()的线程会被存储到线程池中
  • notify(): 唤醒线程池中的任意一个线程
  • notifyAll(): 唤醒线程池中的所有线程

/*
    *** 等待唤醒机制的基本示例 ***
多个线程操作同一资源,任务不同,使用相同的锁
确保每输入一项,就相应的输出一项
*/


//定义资源
class Source1  //资源1,包含一些人的姓名和性别
{
	String name;
	String sex;
	boolean flag = false;  //一般都会定义标志位
}

//定义任务1,负责输入姓名和年龄
class Input1 implements Runnable
{
	//为保证不同线程操作同一资源,这里不要实例化资源,而是以参数形式传递给构造函数
	Source1 s;  	
	Input1(Source1 s)
	{
		this.s = s;
	}
	
	//覆盖run方法
	public void run()
	{
		int x = 0;
		while(true)
		{
			synchronized(s)  //保证不同线程使用的锁是惟一的
			{
				while(s.flag)
					try{s.wait();}catch(InterruptedException e){}  //每次唤醒都会判断flag,确定是否输入
				//flag为true,则等待
				//if(flag)  //导致不该运行的线程运行了,产生数据输出错误
				if(x==0)
				{
					s.name = "mike";
					s.sex = "man";
					System.out.println(Thread.currentThread().getName()+"...Input....name= "+s.name+"...Input...sex= "+s.sex);
				}
				else
				{
					s.name = "花花";
					s.sex = "***famale***";
					System.out.println(Thread.currentThread().getName()+"...Input....name= "+s.name+"...Input...sex= "+s.sex);
				}
				x = (x+1)%2;  //0,1切换机制
				s.flag = true;
				//s.notify();  //while+notify,会出现死锁:所有线程处于等待状态
				s.notifyAll();	
			}
		}
		
	}
	
}

//定义任务2,负责输出姓名和年龄
class Output1 implements Runnable 
{
	Source1 s;  	
	Output1(Source1 s)
	{
		this.s = s;
	}
	
	public void run()
	{
		while(true)
		{
			synchronized(s)
			{
				while(!s.flag)
					try{s.wait();}catch(InterruptedException e){}  //每次唤醒都会判断flag,确定是否输出
				System.out.println(Thread.currentThread().getName()+"...Output...name= "+s.name+"...Output..sex= "+s.sex);
				System.out.println();
				s.flag = false;
				s.notifyAll();				
			}
		}
	}
}


class WaitNotifyDemo
{
	public static void main(String[] args)
	{
		//创建资源
		Source1 s = new Source1();
		//创建任务
		Input1 in = new Input1(s);
		Output1 out = new Output1(s);
		//创建线程
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		
		//开启线程
		t1.start();
		t2.start();
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值