[英]Printing Odd and Even number using 2 threads?
我已经尝试过此代码。 但是在打印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();
我哪里错了? 谢谢。
PS:我知道这类问题已经问过很多次了,但我想自己尝试一下。
我的猜测是你是。
编辑:运行代码后,OP修复了代码,它会打印
0
1
如预期的那样。 有时可能会随机打印0和0,因为第一次检查奇数/偶数不同步。
这是一个简单的僵局:
线程1等待有人通知锁。 线程2等待有人通知相同的锁。
由于没有人去过o.notify();
, 什么都没发生。
当两个线程都启动时, i
为0,因此都先调用printEven()
。 现在,当发生这种情况时,两个线程将在下一轮调用printOdd()
。
基本概念是当一个线程正在运行时,另一个线程必须等待。 一旦线程打印了值,它就必须等到另一个线程打印出来。 这是通过使用等待/通知机制来实现的。
当奇数线程完成打印值时,它将通知等待线程(偶数线程),并且偶数线程准备就绪,可以运行,但将等待奇数线程释放锁定。 现在,奇数线程调用在更衣室对象上等待,以便它释放锁并进入等待状态。 在这一点上,唯一等待锁对象锁定的线程是偶数线程并且它正在运行。 此过程将继续进行。
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);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.