我试过这段代码。但是在打印0之后,它不会打印任何内容。 由于我认为有些锁定,它会阻塞。
public class EvenOdd implements Runnable {
private Object o = new Object();
private volatile int i = 0;
public void run() {
try {
System.out.println();
if ( Thread.currentThread().getName().equals( "Even")) {
printEven();
} else {
printOdd();
}
} catch ( Exception ee) {
ee.printStackTrace();
}
}
private void printEven() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 == 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
private void printOdd() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 != 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
}
我的TestClass:
EvenOdd x = new EvenOdd();
new Thread(x,"Even").start();
new Thread(x,"Odd").start();
我哪里错了? 感谢。
P.S:我知道很多次都会问这类问题,但我想亲自尝试。答案 0 :(得分:1)
我的猜测是你;
编辑:运行代码后,OP修复了代码,打印
0
1
正如所料。它有时可能随机打印0和0,因为奇数/偶数的第一次检查不同步。
答案 1 :(得分:0)
这是一个简单的僵局:
线程1等待有人通知锁定。线程2等待某人通知同一个锁。
由于没有人到达o.notify();
,所以没有任何事情发生。
当两个线程都开始时i
为0,因此首先调用printEven()
。现在,当发生这种情况时,两个线程将在下一轮中调用printOdd()
。
答案 2 :(得分:0)
基本概念是当一个线程正在运行时,另一个线程必须等待。一旦线程打印出值,它就必须等到另一个线程打印出来。这是通过使用wait / notify机制实现的。
当奇数线程完成打印值时,它会通知等待线程(偶数线程)并且偶数线程已准备好运行,但将等待奇数线程释放锁定。现在奇数线程调用等待锁定器对象,以便它释放锁并进入等待状态。此时,等待锁定对象锁定的唯一线程是Even thread并且它会运行。这个过程可以继续。
public class Test {
public static void main(String[] args) {
Object locker = new Object();
Thread t1 = new Thread(new OddWorker(locker));
Thread t2 = new Thread(new EvenWorker(locker));
t1.start();
t2.start();
}
}
class OddWorker implements Runnable {
private Object locker;
private int number = 1, count = 1;
OddWorker(Object locker) {
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
locker.notify();
}
}
}
class EvenWorker implements Runnable {
private Object locker;
private int number = 2, count = 1;
EvenWorker(Object locker) {
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
}
}
}