2016-02-05 51 views
0

我寫了一個小樣本代碼:多線程:上下文切換

public class Button2 implements Runnable{  
    JButton jButton = new JButton(); 
    static boolean changeContext = false;  
    public Button2(){ 
     jButton.setText("ButtonTWO"); 
     jButton.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       changeContext = true; 
       ((JButton)e.getSource()).setEnabled(false); 
      } 
     }); 
    } 
    @Override 
    public void run() { 
     System.out.println("ButtonTWO run..."); 
     jButton.setEnabled(true); 
     while(true){ 
      if(changeContext) 
       break; 
     } 
     changeContext = false;   
    } 
} 

當我運行它想:

Button2 threadTWO = new Button2(); 
Thread thread2; 
      try{ 
       thread2 = new Thread(threadTWO); 
      thread2.start(); 
      thread2.join(); 
      }catch(Exception ex){ 
       System.out.println("Ëxception caught"); 
      } 

它從來沒有出來,即使點擊了按鈕之後。

如果我在while(true) in run method之後加上一個sysoutThread.sleep(1),它會出現while循環。可能的原因是什麼?

回答

0

我假設你正在運行EDT的底部。因此,您正在創建按鈕(並希望以某種方式將其添加到您的用戶界面中),然後啓動線程並使EDT等待線程死機(thread2.join()),因此EDT無法處理事件,並且changeContext = true永遠不會被調用。

,添加的東西,使循環的結束可能是由於缺少括號:

這只是結束循環,如果changeContext是真實的:

if(changeContext) 
    break; 

我認爲你這樣做:

if(changeContext) 
    Thread.sleep(1); 
    break; 

上述調用睡眠,如果changeContext爲真,然後立即結束循環(break不在if區塊anymo回覆。所以,如果你想一致的行爲,寫這樣的:

if(changeContext) { 
    Thread.sleep(1); 
    break; 
} 

順便說一下,蘋果公司去年基本上也有類似的源(雙break並沒有括號)有一個安全問題。

+0

它在while(true){Thread.sleep(1); if(....)}之後添加Thread.sleep時起作用 –