Java 使用两个线程按顺序打印数字
这是一个面试问题,我认为它与现实生活中的实际问题没有任何关系。 我必须打印12345号。。。。按顺序,但条件是我必须使用两个线程来打印,一个负责打印奇数,另一个负责打印偶数Java 使用两个线程按顺序打印数字,java,multithreading,concurrency,Java,Multithreading,Concurrency,这是一个面试问题,我认为它与现实生活中的实际问题没有任何关系。 我必须打印12345号。。。。按顺序,但条件是我必须使用两个线程来打印,一个负责打印奇数,另一个负责打印偶数 到目前为止,我已经想出了这个解决办法 package junk.concurrency; public class PrintEvenOddTester { public static void main(String... args) { TaskEvenOdd t = new Task
到目前为止,我已经想出了这个解决办法
package junk.concurrency;
public class PrintEvenOddTester {
public static void main(String... args) {
TaskEvenOdd t = new TaskEvenOdd(10);
Thread t1 = new Thread(t, "odd printer");
Thread t2 = new Thread(t, "even printer");
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
private int max;
private boolean isOdd = true;
private int number = 1;
TaskEvenOdd(int max) {
this.max = max;
}
synchronized void printEven(int number) { // sync on runnable itself
while (isOdd) { // if odd is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even:" + this.number); // LINE-1
isOdd = true;
this.number++; // LINE-2
notifyAll();
}
synchronized void printOdd(int number) { // sync on runnable itself
while (!isOdd) { // if even is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Odd:" + this.number); // LINE-3
this.number++; // LINE-4
isOdd = false;
notifyAll();
}
@Override
public void run() {
while (number <= max) {
if (Thread.currentThread().getName().equals("even printer")) {
printEven(number);
} else {
printOdd(number);
}
}
}
}
package.junk.concurrency;
公共类打印测试仪{
公共静态void main(字符串…参数){
TaskEvenOdd t=新TaskEvenOdd(10);
线程t1=新线程(t,“奇数打印机”);
线程t2=新线程(t,“偶数打印机”);
t1.start();
t2.start();
}
}
类TaskEvenOdd实现可运行{
私人int max;
私有布尔值isOdd=true;
私有整数=1;
奇数(整数最大值){
this.max=max;
}
同步的void print偶数(整数){//sync on runnable本身
while(isOdd){//如果要打印奇数,请等待
试一试{
等待();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
System.out.println(“偶数:+this.number);//第1行
isOdd=真;
this.number++;//第2行
notifyAll();
}
synchronized void printOdd(整数){//sync on runnable本身
而(!isOdd){//如果要打印偶数,请稍候
试一试{
等待();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
System.out.println(“奇数:+this.number);//第3行
this.number++;//第4行
isOdd=假;
notifyAll();
}
@凌驾
公开募捐{
而(数量1)
你的问题是,你的方法的参数也被称为number。因此它是隐藏你的类的字段!因此,当你省略时,你将参数加进去;这根本没有任何实际效果
此问题有两种解决方案:
a) 简单地避免这样做(因此,按照惯例,避免使用与参数和字段相同的名称)
b) 使用能够发现此类问题并告诉您的工具。例如,findbugs可以明确告诉您有关阴影的信息。并且可能还可以告诉IDE对此发出警告。请参阅
二,
考虑到这只是一个“简单”的作业……在我看来,简单检查一下全班的“极限”就可以了。我想知道我为什么没有观察到这么小的事情……谢谢你指出这一点。你能对问题的第二部分发表评论吗。“使用能够发现此类问题并告诉你的工具”请详细说明这一点。如果案例2有其他解决方案,请让我知道。添加了此类工具的示例。如果我在面试中问过这个问题,我想要的答案是,“这是一件非常愚蠢的事情。如果你想让任何程序按照特定的顺序完成一系列事情,正确的方法是在一个线程中完成所有的事情。”如果有人问我这个问题,然后说,“好吧,但无论如何要做,“我将创建一个通用解决方案,其中任意数量的线程通过阻塞队列
将令牌从一个线程传递到另一个线程来进行轮换:当一个线程收到令牌时,它就轮到它了。当它完成时,它将令牌交给下一个线程。