Java基礎-多執行緒
阿新 • • 發佈:2019-02-18
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(); } }