主執行緒 和子執行緒的同步控制
阿新 • • 發佈:2019-01-31
有道面試題 子執行緒迴圈10次 然後 主執行緒 迴圈100次 如此往復50次 通過主執行緒和子執行緒的同步實現
public class Test { public static void main(String args[]) { //子執行緒迴圈10次,主執行緒迴圈100次 如此迴圈50次 new Thread( new Runnable(){ @Override public void run() { for(int i=0;i<50;i++) { synchronized(Test.class) { for(int j=0;j<10;j++) { System.out.println("sub thread "+i+" loop of "+j); } } } } }).start(); for(int i=0;i<50;i++) { synchronized(Test.class) { for(int j=0;j<10;j++) { System.out.println("main thread "+i+" loop of " +j); } } } } }
通過synchronized位元組碼的方式 鎖定 需要同步的內容顯得簡單粗暴 這樣 在子執行緒迴圈的內部的10次的時候不會被打斷 而主執行緒內部迴圈的10次也不會被子執行緒打斷
第二種方式 把主執行緒和子執行緒的方法寫到一個類裡面 這樣就能鎖同樣的一個物件,synchronized 載入方法前面表示鎖這個物件,這種方式更易於細粒度的控制執行緒
public class Test { public static void main(String args[]) { final Business business=new Test().new Business(); //子執行緒迴圈10次,主執行緒迴圈100次 如此迴圈50次 new Thread( new Runnable(){ @Override public void run() { for(int i=0;i<50;i++) { business.sub(i); } } }).start(); for(int i=0;i<50;i++) { business.main(i); } } class Business { public synchronized void sub(int i) { for(int j=0;j<10;j++) { System.out.println("sub thread "+j+" loop of "+i); } } public synchronized void main(int i) { for(int j=0;j<10;j++) { System.out.println("main thread "+j+" loop of " +i); } } } }
下面的繼續 我們上面只是實現了互斥 但是並沒有通訊, 讓子執行緒和主執行緒輪流執行 ,接下來 我們通過設定一個bool變數 以及 通過物件this.wait 和this.notifyAll 來控制執行緒的同步
package uses; import java.util.Timer; import java.util.TimerTask; import org.python.modules.synchronize; import org.python.util.PythonInterpreter; public class Test { public static void main(String args[]) { final Business business=new Test().new Business(); //子執行緒迴圈10次,主執行緒迴圈100次 如此迴圈50次 new Thread( new Runnable(){ @Override public void run() { for(int i=0;i<50;i++) { business.sub(i); } } }).start(); for(int i=0;i<50;i++) { business.main(i); } } class Business { private boolean bShouldSub=true; public synchronized void sub(int i) { if(bShouldSub) { //如果這個變數為true 表示該子執行緒執行 for(int j=0;j<10;j++) { System.out.println("sub thread "+j+" loop of "+i); } //執行完畢 設定bShouldSub為false bShouldSub=false; //同時通知 等待this物件的執行緒 this.notifyAll(); } else{ //如果這個變數 為false 表示 主執行緒正在執行,子執行緒需要等待 try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public synchronized void main(int i) { if(bShouldSub) { //這個時候主執行緒需要等待 try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { for(int j=0;j<10;j++) { System.out.println("main thread "+j+" loop of " +i); } //執行完畢後 將變數設定為true 讓子執行緒執行 bShouldSub=true; //通知等待的子執行緒 this.notifyAll(); } } } }