多线程间的通讯之等待唤醒机制

线程间的通讯:

事实上就是多个线程在操作同一个资源。

可是操作动作不同

样例:

需求:模拟简单卖票系统(输入一个人。紧接着输出一个人)

class Res
{
	String name;
	String sex;
}
class Input  implements Runnable
{
	private Res r;
	private int t=0;
	Input(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			if(t==1)
			{
				r.name="nike";
				r.sex="man";
			}
			else
			{
				r.name="丽丽";
				r.sex="女女";
			}
			t=(t+1)%2;
		}
	}
}
class Output  implements Runnable
{
	private Res r;
	Output(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			System.out.println("output....."+r.name+"+++"+r.sex);
		}
	}
}
class InputOutputDemo
{
	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();
	}
}

出现了安全问题(输出了丽丽  MAN)

同步后

class Res
{
	String name;
	String sex;
}
class Input  implements Runnable
{
	private Res r;
	private int t=0;
	Input(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(Res.class)
			{
				if(t==1)
				{
					r.name="nike";
					r.sex="man";
				}
				else
				{
					r.name="丽丽";
					r.sex="女女";
				}
				t=(t+1)%2;
			}
		}
	}
}
class Output  implements Runnable
{
	private Res r;
	Output(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(Res.class)
			{
				System.out.println("output....."+r.name+"+++"+r.sex);
			}
		}
	}
}
class InputOutputDemo2
{
	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 Res
{
	String name;
	String sex;
	boolean flag;
}
class Input  implements Runnable
{
	private Res r;
	private int t=0;
	Input(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(r)
			{
				if(r.flag)
					try{r.wait();}catch(Exception e){}
				if(t==1)
				{
					r.name="nike";
					r.sex="man";
				}
				else
				{
					r.name="丽丽";
					r.sex="女女";
				}
				t=(t+1)%2;
				r.flag=true;
				r.notify();
			}
		}
	}
}
class Output  implements Runnable
{
	private Res r;
	Output(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(r)
			{
				if(!r.flag)
					try{r.wait();}catch(Exception e){}
				System.out.println("output....."+r.name+"+++"+r.sex);
				r.flag=false;
				r.notify();
			}
		}
	}
}
class InputOutputDemo3
{
	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();
	}
}

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

wait:

notify();

notifyAll();

都使用在同步中,由于要对持有监视器(锁)的操作。

所以要使用在同步中,由于仅仅有同步才具有锁。

为什么这些操作线程的凤飞飞要定义Object类中呢?

由于这些方法在操作同步中线程时。都必需要标识它们所操作线程中的锁,

仅仅有同一个锁上的被等待线程。能够被同一个锁上notify唤醒。

不能够被不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。

而锁能够是随意对象,所以能够被随意对象调用的方法定义Object类中。

以下进行代码改良:

class Res
{
	private String name;
	private String sex;
	private boolean flag;
	public synchronized void  set(String name,String sex)
	{
		if(this.flag)
		  try{this.wait();}catch(Exception e){}

		this.name=name;
		this.sex=sex;

		this.flag=true;
		  this.notify();

	}
	public synchronized void out()
	{
		if(!this.flag)
		 try{this.wait();}catch(Exception e){}
		System.out.println("output....."+this.name+"+++"+this.sex);
		this.flag=false;
				this.notify();
	}
}
class Input  implements Runnable
{
	private Res r;
	private int t=0;
	Input(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(r)
			{
				if(t==1)
					r.set("nike","man");
				else
					r.set("丽丽","女女女");
				t=(t+1)%2;
			}
		}
	}
}
class Output  implements Runnable
{
	private Res r;
	Output(Res r)
	{
		this.r=r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(r)
			{
				r.out();
			}
		}
	}
}
class InputOutputDemo4
{
	public static void main(String[] args)
	{
		Res r=new Res();
		new Thread(new Input(r)).start();
		new Thread(new Output(r)).start();
		/*
		Input in=new Input(r);
		Output out=new Output(r);
		Thread t1=new Thread(in);
		Thread t2=new Thread(out);
		t1.start();
		t2.start();
		*/
	}
}
时间: 2024-12-28 15:00:15

多线程间的通讯之等待唤醒机制的相关文章

java 中多线程之间的通讯之等待唤醒机制

wait notify () nitifyAll () 都使用在同步中,因为要对持有监视器(锁)的线程操作 所以要使用在同步中,因为只有同步才具有锁 为什么这些操作线程的方法要定义object类中呢 因为这些方法在操作同步中线程时.都必须要标识他们所操作线程只有的锁 只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒 不可以对不同锁中的线程进行唤醒 也就是说,等待和唤醒必须是同一个锁 而锁可以使任意对象,所以可以被任意对象调用的方法定义object类中 1 class Res 2 {

多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)

一.多线程之间的通信. 就是多个线程在操作同一份数据, 但是操作的方法不同. 如: 对于同一个存储块,其中有两个存储位:name   sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据. 为了解决上述问题中的安全问题(在存放线程进行存放操作的时候, 打印线程不能对共有数据进行操作),所以应当对两个线程       操作共有数据的代码部分进行同步(使用synchronized(),来进行同步, 注意 :使用同一个对象作为同步锁. 二.等待唤醒机制. 在上述案例实现过后运行,会发现:打印

java多线程——线程间通信之线程等待唤醒机制

三个方法 wait() notify() notifyAll() 三个方法都使用在同步中,因为要对持有锁(又叫监控)的线程操作. 所以要使用在同步中,因为只有同步才具有锁. 为什么这些操作线程的方法均出现在Object类中? 因为这些方法在操作同步中的线程时候,都必须要标识所操作线程识有锁.只有同一个锁上的被等待的线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒. 也就是说,等待和唤醒必须是同一个锁. public class Demo1 { public static

阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第4节 等待唤醒机制_5_线程间通信

原文地址:https://www.cnblogs.com/wangjunwei/p/11261286.html

JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread

Android-Java多线程通讯(生产者 消费者)&10条线程对-等待唤醒/机制的管理

上一篇博客 Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 是两条线程(Thread-0 / Thread-1) 在被CPU随机切换执行: 而今天这篇博客是,在上一篇博客Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 的基础上,扩大规模增加10条线程去执行 生产者 消费者: 注意:?? 上一篇博客是两条线程在执行(生产者 消费者)例如:当Thread-0 锁.wait(); 等待 冻结后,  Thread-1 锁.notify(); 唤醒的一定是 T

多线程等待唤醒机制之生产消费者模式

上篇楼主说明了多线程中死锁产生的原因并抛出问题--死锁的解放方案,那么在本篇文章,楼主将引用一个KFC生产汉堡,顾客购买汉堡的过程来说明死锁解决方案及多线程的等待唤醒机制. 简单地用一幅图来说明KFC生产汉堡,顾客来消费的过程: 场景分析: 资源类:Hamburger 设置汉堡数据:SetThread(生产者) 获取汉堡数据:GetThread(消费者) 测试类:HamburgerTest 不同种类的线程(生产者.消费者)针对同一资源(汉堡)的操作 当汉堡有存货的时候,汉堡师傅不再生产,顾客可消

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

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

多线程进阶之等待唤醒机制

/* * 线程间通讯实例 * 多个线程在处理同一资源,但是任务不同 */ //资源 class Resource { String name; String sex; } //输入 class Input implements Runnable { Resource r;//类对象 public Input(Resource r)//类对象做构造参数-->初始化资源 { this.r=r; } public void run() { int x=0; while(true) { /* * 加上同