1. 程式人生 > >Java基礎-多執行緒

Java基礎-多執行緒

class Res
{
	String name;
	String sex;
	Boolean flag =false;
//	private String name;
//	private String sex;
//	private Boolean flag =false;

//	public synchronized void set(String name,String sex)
//	{
//			if(flag)
//		try{this.wait();}
//		catch(exception e){}
//		this.name = name;   //因為可能賦值的時候卡在這
//		this.sex = sex;
//		flag = true;
//		this.notify();
//	}


//	public synchronized void out()
//	{
//		if(!flag)
//		try{this.Wait();}
//		catch(exception e){}
//		System.out.println(name+"....."+sex);
//		flag = false;
//		this.notify();


//	}
}


class Input implements Runnable
{
	private Res r;
	//Object obj = new object();// 1  用了1處的程式碼同步依然會出現問題,因為不滿足兩個前提的第二個,不是同一個鎖
	//因為這裡的Object obj = new object();跟輸出的Object obj = new object();,
	//指的不是同一個,因此兩個的鎖不一樣。

	Input(Res r)
	{
		this.r =r;
	}


	public void run()
	{
		int x = 0;
		while(true)
		{
		
		   
		//{
			//if(r.flag)//有這個顏色用的是等待喚醒機制。
			//try{r.Wait();}
			//catch(exception e){}

	//	因為在使用wait()的時候會丟擲異常所以必須使用try,同時也要用r.wait
	//	因為wait在其他執行緒呼叫此物件notify()或notifyall()方法前,導致當前執行緒等待。
	//	換句話說,此方法的行為就好像他僅執行wait(0)呼叫一樣。
	//	當前執行緒必須擁有此物件的監視器。該執行緒釋出對此監視器的所有權並等待,
	//	知道其他執行緒通過呼叫notify方法,或notifyall方法通知再次物件的監視器上等待的執行緒醒來。
	//	然後該執行緒將等到重新獲得對監視器的所有權後才能繼續執行。
	//	





		//synchronized(obj)  //1  
		//用程式碼 2 就OK了,因為R都是同樣的物件,
		// 所以所也一樣,或者可以寫input.class,output.class,只要唯一的都可以寫,
		// 但是現在列印會出現輸入很多次然後列印很多次,最好實現輸一次,
		// 列印一次,3  程式碼,解決這個問題
		  synchronized(r) //2
	{
		if(r.flag)//3  有這個顏色用的是等待喚醒機制。
			try{r.wait();}  //3  為什麼不能拋????????
			catch(Exception e){} //3
		if(x==0)
		{
			r.name = "mike";
			//易出現問題
			r.sex = "man";
		}
		else
		{
			r.name="麗麗";
			//易出現問題

			r.sex="女女女";

		}

		x=(x+1)%2;
		r.flag =true;  //3
		r.notify();//3   因為在res中寫了公共介面函式
	}
//r.flag =true;
//r.Notify();//因為在res中寫了公共介面函式
//所以可以用下面的代替
//if(x==0)
//R.set("mike","man");
//Else
//R.set("麗麗","女女女女");
//X=(x+1)%2;
	}
  }
}



class Output implements Runnable
{
	private Res r;
	//Object obj = new object();  //1
	Output(Res r)
	{
		this.r=r;//this.r是private res r;
	}
	public void run()
	{
			while(true)
		{
		//Synchronized(obj)
		//Synchronized(r)
		//{
		//if(!r.flag)//如果執行緒notify之後,沒到這個wait(),執行權就被搶走了,那麼也沒事,過程還是一樣的(可以看看程式碼)
		//try{r.Wait();}catch(exception e){}  //放棄執行權
		//System.out.println(r.name+"...."+r.sex);
		//r.flag =flase;
		//r.Notify();//通知別的執行緒活了
		//}res寫了公共函式,所以可以用下面的代替
		//synchronized(obj) //1
		synchronized(r) //2
		{
			//如果執行緒notify之後,沒到這個wait(),
			//執行權就被搶走了,那麼也沒事,過程還是一樣的(可以看看程式碼)
			if(!r.flag) //3
			try{r.wait();}catch(Exception e){} //3  //放棄執行權
			System.out.println(r.name+"...."+r.sex);
			r.flag =false; //3
			r.notify();//3   //兩撥小朋友  一撥的只能喚醒自己的一撥
		}
			//r.out();
		}
	}


}

class InputOutputDemo
{
	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();
	
	}


}

十.多執行緒-執行緒通訊-生產者消費者問題