没有旗帜可以吗?我只能使用notify / wait / synchronized。 我想打印:worker1 worker2 worker3 worker1 worker2 ...但我有wait()/ notify()方法的竞争条件。
class ThirdWorker implements Runnable {
@Override
public void run(){
for (int i = 0; i < a; i++) {
synchronized (mutex3) {
System.out.println(Thread.currentThread().getName() + " worker3 " + (i + 1));
try {
mutex3.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mutex) {
mutex.notify();
}
}
}
}
}
class SecondWorker implements Runnable{
@Override
public void run() {
synchronized (mutex) {
new Thread(new ThirdWorker()).start();
}
for (int i = 0; i < a; i++) {
synchronized (mutex2) {
System.out.println(Thread.currentThread().getName() + " worker2 " + (i + 1));
synchronized (mutex3){
mutex3.notify();
}
try {
mutex2.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class FirstWorker implements Runnable{
@Override
public void run() {
synchronized (mutex) {
new Thread(new SecondWorker()).start();
for (int i = 0; i < a; i++) {
System.out.println(Thread.currentThread().getName() + " worker 1 " + (i+1));
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mutex2){
mutex2.notify();
}
}
}
}
}
new Thread(new FirstWorker()).start();
我知道使用旗帜很容易做到,但我不能。
答案 0 :(得分:0)
这里有一个如何做到的例子。
注意:强>
属性turnIsFor
是受保护的资源
线程创建为兄弟姐妹
用作监视器的对象(lock
)除了那之外不用于任何其他内容
while
包含lock.wait()
,其条件应该使线程能够运行
lock
和notify
都必须位于synchronized
区块内
另请注意,我故意以随机顺序启动线程,但仍然按照共享属性nextTurnIsFor
给出的预期顺序一次一个。
public class ThreeThreads {
Thread t1, t2, t3;
Lock lock = new Lock();
int turnIsFor = 1;
public static void main(String ... args) {
ThreeThreads threeThreads = new ThreeThreads();
threeThreads.run();
}
public ThreeThreads() {
Runnable printName1 = new Runnable() {
int turn = 1;
@Override
public void run() {
while(true){
try {
synchronized(lock) {
while(turnIsFor != turn){
lock.wait();;
}
System.out.println( Thread.currentThread().getName());
turnIsFor = 2;
lock.notifyAll();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
};
Runnable printName2 = new Runnable() {
int turn = 2;
@Override
public void run() {
while(true) {
try {
synchronized(lock) {
while(turnIsFor != turn){
lock.wait();;
}
System.out.println( Thread.currentThread().getName());
turnIsFor = 3;
lock.notifyAll();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
};
Runnable printName3 = new Runnable() {
int turn = 3;
@Override
public void run() {
while(true) {
try {
synchronized(lock) {
while(turnIsFor != turn){
lock.wait();;
}
System.out.println( Thread.currentThread().getName());
turnIsFor = 1;
lock.notifyAll();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
};
t1 = new Thread(printName1, "Thread 1");
t2 = new Thread(printName2, "Thread 2");
t3 = new Thread(printName3, "Thread 3");
}
public void run() {
t3.start();
t1.start();
t2.start();
}
private static final class Lock{};
}