为什么BufferedReader.ready()在第二次创建相同的线程时不起作用?

时间:2012-10-31 09:55:07

标签: java

我有三个课程如下:

第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();
       }

    }
  }
}

第2课:

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

First类是创建线程的主类,它每5秒创建两个新线程。

第一个线程(SendThreadSys1)将通过发送字符串" BYE"从开始时间起每4秒后停止第二个线程(ReceivedThreadSys1)。到标准i / p流。 在前4秒钟,我可以从控制台键入,并在控制台中打印字符串。但是在主类中第二次创建新线程后(即5秒后), 程序没有检测到来自控制台的任何输入。

第二次没有从控制台检测到任何输入的原因是什么?

1 个答案:

答案 0 :(得分:0)

我尝试了你发布的代码,它似乎有效。但是,我确实注意到一个可能的多线程问题可能会影响它是否始终适用于所有系统,因此可能成为问题。

在SendThreadSys1代码中,您有:

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

只是写入将在另一个线程中使用的变量。由一个线程完成的写入不会自动用于另一个线程中的读取。我看不到任何明显的东西,确保当另一个线程中的run方法读取时,引用的br写入是可见的。

如果你有一个可以重现问题的系统,我建议通过静态同步的get和set方法,将read私有化为ReceivedThreadSys1,并且只更新和访问它,即使在ReceivedThreadSys1中也是如此。

顺便说一句,它应该只是Thread.sleep(5000)等.Thread.sleep是一个静态方法,只能睡眠调用线程。