package 多线程;

public class ThreadcommunicateSafe1 {
	public static void main(String[] args) {
		Info3 mess= new Info3();
		Input3 in = new Input3(mess);
		Output3 out = new Output3(mess);
		new Thread(in).start();
		new Thread(out).start();
	}

}
//1,等待唤醒机制 实现 Input线程和Output线程交替获取执行权交替复活执行
//线程Input第一次唤醒线程Output第二次自己等待,线程Output第一次自己等待Input第二次 唤醒线程
//用来存放输入的内容  以及输出的源头   存放空间或者源头都只有一个且是同一个   可以想到单例设计模式
//或者 通过函数调用 同一个对象  就是  输入方 与输出方调用的是 同一个对象  就可保证 存放空间或者源头都只有一个且是同一个
class Info3{
	private String name;
	private String sex;
	private boolean flag=true;
	public synchronized void set(String name,String sex){
		if(!flag)
			try {
				this.wait();//线程等待
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		this.name = name;
		this.sex = sex;
		flag=false;
		this.notify();
	}
	public synchronized void sop(){
		if(flag) //如果为真的话 就让本线程等待     
			try {
				this.wait();//导致当前线程等待。 当前线程必须拥有此对象监视器。 
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		//如果为假的话 执行以下代码,然后将flag设置为true(那么下一次该线程执行的时候 就会遇真而等待)并唤醒所有线程
		System.out.println(Thread.currentThread().getName()+"名字:"+name+"。。。。__性别:"+sex);
		flag = true;
		this.notify();//唤醒在此对象监视器上等待的所有线程。
	}
}
class Input3 implements Runnable{
	Info3 info;
	public Input3(Info3 info) {
		this.info=info;
	}
	@Override
	public void run() {
		int x = 0;
		while (true) {
			if (x==0) {
				info.set("demo", "man");
			} else {
				info.set("丽丽", "女生");
			}
			x=(x+1)%2;
		}
	}
}
class Output3 implements Runnable{
	Info3 info;
	public Output3(Info3 info) {
		this.info=info;
	}
	public void run() {
		while (true) {
			info.sop();
		}
	}
}
//2,通过创建一个标记flag 让Input线程和Output线程交替执行代码 但是Input线程和Output线程 还是随机获取执行权
//class Info2{
//	String name;
//	String sex;
//	boolean flag;
//}
//class Input2 implements Runnable{
//	Info2 info;
//	int x = 0;
//	public Input2(Info2 info) {
//		this.info=info;
//	}
//	@Override
//	public void run() {
//		while (true) {
//			if(info.flag){ //当flag为真的时候执行一下代码
//				synchronized(info){
//				if (x==0) {
//					info.name = "demo";
//					info.sex = "man";
//				} else {
//					info.name = "莉莉";
//					info.sex = "女生";	
//				}
//				x=(x+1)%2;
//				info.flag=false;//此时 本线程 无法执行run中的主要代码  让output线程能够执行其run中的主要代码
//				}
//			}
//		}
//	}
//}
//class Output2 implements Runnable{
//	Info2 info;
//	public Output2(Info2 info) {
//		this.info=info;
//	}
//	public void run() {
//		while (true) {
//			if(info.flag==false){ //当flag为false的时候 本线程可以执行以下代码
//				synchronized(info){
//				System.out.println("名字:"+info.name+"__性别:"+info.sex);
//				info.flag = true;//开启 input的开关  让input线程能够执行其run中的主要代码
//				}
//			}
//			
//		}
//	}
//}