2012-10-31 45 views
3

我有如下三類:爲什麼在第二次創建同一個線程時BufferedReader.ready()不工作?

第1類:

public class System1Class { 

public static void main(String args[]) throws IOException { 

    while(true) // Every 5 seconds it will create below two new threads. 
    { 
     System.out.println("New threads created."); 
     Thread sndThreadSys1 = new Thread(new SendThreadSys1(), "SendThreadSys1"); 
     Thread rcvThreadSys1 = new Thread(new ReceivedThreadSys1(), "ReceivedThreadSys1"); 

     sndThreadSys1.start(); 
     rcvThreadSys1.start(); 

    try { 
     Thread.currentThread().sleep(5000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 

    } 
    } 
} 

二級:

public class SendThreadSys1 implements Runnable{ 

public void run() { 

    try { 
     Thread.currentThread().sleep(4000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    String st = "BYE"; 
    InputStream is = new ByteArrayInputStream(st.getBytes()); 
    System.setIn(is); 
    ReceivedThreadSys1.br = new BufferedReader(new InputStreamReader(System.in)); // refresh the br object 

    } 

} 

3類:

public class ReceivedThreadSys1 implements Runnable{ 

public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
public void run() { 

    try{ 
     while(true) 
     { 
      while(!br.ready()) // waiting for input from console/Std i/p Stream 
      { 
       try { 
        Thread.sleep(200); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      String s = br.readLine(); 
      System.out.println("Print :::"+s); 
      if(s.equals("BYE")) 
      { 
       break; 
      } 
     } 

     System.out.println("I am outside."); 
    } 
    catch(IOException e) 
    { 
     e.printStackTrace(); 
    } 
    } 
} 

第一類是主類線程在哪裏創建,並且每5秒創建兩個新線程。

第一個線程(SendThreadSys1)將通過將字符串「BYE」發送到標準I/P流,從其開始時間開始每隔4秒後停止第二個線程(ReceivedThreadSys1)。 在前4秒內,我可以從控制檯輸入字符串並將其打印在控制檯中。但是,在主類中第二次創建新線程(即5秒後)之後,程序未檢測到來自控制檯的任何輸入。

什麼可能是第二次未檢測到任何控制檯輸入的原因?

+0

我剛剛掃描了你的代碼真的很快。但我認爲問題在於你不關閉BufferedReaders。因此,如果您創建一個新文件,它將無法訪問該文件,因爲它被第一個閱讀器鎖定。 – moeTi

+0

我應該在哪裏放br.close()? – Angom

+0

添加一個finally {br.close(); }到Class3中的try-catch。所以在你離開線程之前,BufferedReader將被關閉。 – chrise

回答

0

我試過你的發佈代碼,它似乎工作。但是,我確實注意到可能會影響它是否始終適用於所有系統的可能的多線程問題,因此可能是是問題。

在你SendThreadSys1代碼,您有:

ReceivedThreadSys1.br = 
    new BufferedReader(new InputStreamReader(System.in)); 

剛剛寫入將在另一個線程中使用的變量。由一個線程完成的寫入不能自動用於另一個線程的讀取。我看不到任何明顯的情況,確保當另一個線程中的run方法讀取它時,引用的br寫入是可見的。

如果您有一個可以重現問題的系統,我建議使用ReceivedThreadSys1作爲私有,並且僅通過靜態同步獲取和設置方法更新並訪問它,即使在ReceivedThreadSys1中也是如此。

順便說一句,它應該只是Thread.sleep(5000)等。Thread.sleep是一個靜態方法,只能睡眠調用線程。

+0

感謝您的回覆。實際上經過幾次測試後,我發現它是因爲類SendErreadSys1中的System.setIn(is)。似乎這條線第二次阻塞了控制檯輸入。我不知道原因,但當我評論這條線時,它的工作。所以,我刪除了行System.setIn(是)並獲得相同的功能,我使用了公共靜態布爾標誌,將由線程訪問。所以每當str =「BYE」時,設置標誌,並在另一個線程中繼續監視標誌。 – Angom

相關問題