我知道之前有人问过这个问题,但我无法弄清楚为什么我的解决方案对我不起作用。我有两个线程偶数和奇数,一个打印偶数,另一个打印奇数。当我启动线程时,我希望输出按数字的自然顺序排列,例如 0 1 2 3.. 等。这是我的代码:- [更新]
public class ThreadCommunication {
public static void main(String... args) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread(){
@Override
public void run()
{
for(int i=0;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
@Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
obj.notify();
}
}
}
};
even.start();
odd.start();
}
当我运行上面的代码时,有时它会按预期的自然顺序打印数字,但有时会以其他顺序打印,例如:
0
1
3
5
7
9
2
我在这里做错了什么?
最佳答案
编辑:
volatile static boolean isAlreadyWaiting = false;
Thread even = new Thread() {
@Override
public void run() {
synchronized (obj) {
for (int i = 0; i < 10; i = i + 2) {
System.out.println(i);
try {
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
obj.notify();
isAlreadyWaiting=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread() {
@Override
public void run() {
synchronized (obj) {
for (int i = 1; i < 10; i = i + 2) {
System.out.println(i);
try {
if(isAlreadyWaiting){
obj.notify();
isAlreadyWaiting = false;
}
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
检查文档
public class IllegalMonitorStateException extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Monitor 属于obj
所以你应该打电话
obj.wait();
和
obj.notify();
有关所有权的更多信息
This methods (wait or notify) should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:
- By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
- For objects of type Class, by executing a synchronized static method of that class.
一次只有一个线程可以拥有一个对象的监视器。
关于java - 在 Java 中制作偶数和奇数线程以自然顺序打印数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35693546/