使用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感谢您的建议,我将负责工作。