[英]Printing Odd Even number sequentially using two threads
我不明白为什么下面的程序不能在偶数情况下工作。
我得到的输出In Odd Thread 1
如果我理解程序执行-
转到t1线程。 条件不满足。 调用notifyAll,它会被忽略。转到t2线程,该线程输出奇数增量并调用wait()。 T2在这种情况下应该开始运行了吗??
public class OddEvenTest {
static int max = 20;
static int count = 1;
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count % 2 == 0 && count < max) {
System.out.println("In even Thread " +count);
count++;
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
lock.notifyAll();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count % 2 != 0 && count < max) {
System.out.println("In Odd Thread " +count);
count++;
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
lock.notifyAll();
}
}
});
t1.start();
t2.start();
}
}
您不想盲目地在lock
同步的循环中使用wait()
。 相反,请检查您的wait
条件,例如
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (count < max) {
synchronized (lock) {
if (count % 2 == 0) {
System.out.println("In Even Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (count < max) {
synchronized (lock) {
if (count % 2 != 0) {
System.out.println("In Odd Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
在Java 8+中,您可以使用以下lambda简化匿名类
Thread t1 = new Thread(() -> {
while (count < max) {
synchronized (lock) {
if (count % 2 == 0) {
System.out.println("In Even Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(() -> {
while (count < max) {
synchronized (lock) {
if (count % 2 != 0) {
System.out.println("In Odd Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
我能想到很多问题
notifyAll已写在循环外,因此请考虑以下情况:奇数线程正在执行并打印该值,并且即将调用wait,但是偶数线程在奇数线程调用等待之前调用了notify,因此奇数线程将始终处于等待状态。 因此,您应该在循环内保持notifyAll。
这是您在执行过程中所经历的。
while循环应继续执行,直到count小于最大数为止,并且应在while循环内部应用偶数或条件。
等待应该在其他情况下
public class OddEvenTest {
static int max = 20;
static int count = 1;
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count < max) {
if(count % 2 == 0 ) {
System.out.println("In even Thread " + count);
count++;
}else{
try {
lock.wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
lock.notifyAll();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count < max) {
if(count % 2 != 0) {
System.out.println("In Odd Thread " + count);
count++;
}else{
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
lock.notifyAll();
}
}
}
});
t1.start();
t2.start();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.