Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用getState方法与线程同步的Java_Java_Multithreading_Parallel Processing_Synchronization_Java Threads - Fatal编程技术网

使用getState方法与线程同步的Java

使用getState方法与线程同步的Java,java,multithreading,parallel-processing,synchronization,java-threads,Java,Multithreading,Parallel Processing,Synchronization,Java Threads,我有两门课: TestClass,一个通过扫描仪使用用户输入的类 class测试类{ 公共静态void main(字符串[]args){ 扫描仪扫描=新扫描仪(System.in); 系统输出打印(“1”); String one=scan.nextLine(); 系统输出打印(“2:”); 字符串二=scan.nextLine(); 系统输出打印(“3:”); 字符串三=scan.nextLine(); } } Test,一个类,它向TestClass提供假输入以对其进行测试 公共类

我有两门课:

  • TestClass,一个通过扫描仪使用用户输入的类
class测试类{
公共静态void main(字符串[]args){
扫描仪扫描=新扫描仪(System.in);
系统输出打印(“1”);
String one=scan.nextLine();
系统输出打印(“2:”);
字符串二=scan.nextLine();
系统输出打印(“3:”);
字符串三=scan.nextLine();
}
}
  • Test,一个类,它向TestClass提供假输入以对其进行测试
公共类测试{
公共静态void main(字符串[]args)引发IOException{
PipedOutputStream inputSimulator=新的PipedOutputStream();
PrintStream inputProvider=新的PrintStream(inputSimulator);
setIn(新的BufferedInputStream(新的PipedInputStream(inputSimulator));
线程线程=新线程(()->TestClass.main(新字符串[]{}));
thread.start();
while(thread.getState()!=thread.State.TIMED\u WAITING);
inputProvider.println(“给定的一个”);
System.out.println(“一个给定”);
while(thread.getState()!=thread.State.TIMED\u WAITING);
inputProvider.println(“两个给定”);
System.out.println(“两个给定”);
while(thread.getState()!=thread.State.TIMED\u WAITING);
inputProvider.println(“三个给定”);
System.out.println(“三个给定”);
}
}
我无法使Test类与TestClass同步。所谓同步,我的意思是,如果我希望在控制台中打印此内容:

1: One given
2: Two given
3: Three given
然而,我得到:

1: One given
Two given
Three given
2: 3:

我使用
while
循环检查线程的扫描器当前是否正在等待输入。但是,在第一次输入之后,这种检查机制不起作用。我需要在不编辑TestClass的情况下执行此操作。实现这一点的方法是什么?

通常依靠线程计时是一个非常糟糕的主意,但是根据您的评论和限制,我能想到的最好方法是使用
线程。睡眠
如下:

    public static void main(String[] args) throws IOException, InterruptedException {
        PipedOutputStream inputSimulator = new PipedOutputStream();
        PrintStream inputProvider = new PrintStream(inputSimulator);
        System.setIn(new BufferedInputStream(new PipedInputStream(inputSimulator)));

        Thread thread = new Thread(() -> TestClass.main(new String[]{}));
        thread.start();

        Thread.sleep(1000);
        while (thread.getState() != Thread.State.TIMED_WAITING) ;
        inputProvider.println("One given");
        System.out.println("One given");

        Thread.sleep(1000);
        while (thread.getState() != Thread.State.TIMED_WAITING) ;
        inputProvider.println("Two given");
        System.out.println("Two given");

        Thread.sleep(1000);
        while (thread.getState() != Thread.State.TIMED_WAITING) ;
        inputProvider.println("Three given");
        System.out.println("Three given");
    }
}

可能,对于您的上下文,您必须添加额外的检查等等。

通常依赖线程计时是一个非常糟糕的主意,但是根据您的评论和限制,我能想到的最好方法是使用
线程。睡眠
如下:

    public static void main(String[] args) throws IOException, InterruptedException {
        PipedOutputStream inputSimulator = new PipedOutputStream();
        PrintStream inputProvider = new PrintStream(inputSimulator);
        System.setIn(new BufferedInputStream(new PipedInputStream(inputSimulator)));

        Thread thread = new Thread(() -> TestClass.main(new String[]{}));
        thread.start();

        Thread.sleep(1000);
        while (thread.getState() != Thread.State.TIMED_WAITING) ;
        inputProvider.println("One given");
        System.out.println("One given");

        Thread.sleep(1000);
        while (thread.getState() != Thread.State.TIMED_WAITING) ;
        inputProvider.println("Two given");
        System.out.println("Two given");

        Thread.sleep(1000);
        while (thread.getState() != Thread.State.TIMED_WAITING) ;
        inputProvider.println("Three given");
        System.out.println("Three given");
    }
}

可能,对于您的上下文,您必须添加额外的检查等等。

它看起来也像是一个未记录的实现细节,从
PipedInputStream
读取的线程进入了
TIMED_WAITING
状态(而不是,例如
WAITING
)。是的,这显然是生产中的禁忌,但是由于无法修改TestClass的限制,我看不到其他解决方法。很好,您可以将
PipedOutputStream
/
PipedInputStream
组合替换为支持查询之前写入的数据已经读取了多少(甚至支持等待)的组合。实际上,只需将一个非常小的缓冲区大小传递给
PipedInputStream​
的构造函数将具有每个
inputProvider.println(…)
等待接收器的效果。如果这就是OP想要的,就不需要更多了。当然,这时不应该使用矛盾的
BufferedInputStream
。@Holger感谢我的建议,我将负责工作。它还看起来像一个未记录的实现细节,从
PipedInputStream
读取的线程根本就进入了
TIMED\u WAITING
状态(而不是,例如,
等待
)是的,这在生产中显然是一个禁忌,但由于无法修改TestClass的限制,我看不到其他解决方法。好的,您可以用支持查询以前写入的数据已经读取了多少的东西来替换
pipedoutpstream
/
PipedInputStream
组合事实上,只需将一个非常小的缓冲区大小传递给
PipedInputStream​
的构造函数将具有每个
inputProvider.println(…)
等待接收者的效果。如果这就是OP想要的,就不需要更多了。当然,不应该使用矛盾的
BufferedInputStream
。@Holger感谢您的建议,我将负责工作。