多线程wait方法报错?

我的问题:三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC。
我编写的代码:

package 并发编程.work2;

public class Test {

private static volatile String CURRENT_THREAD = "A";

public static void main(String[] args) {

Thread t1 = new Thread(new PrintThreadName(), "A");

Thread t2 = new Thread(new PrintThreadName(), "B");

Thread t3 = new Thread(new PrintThreadName(), "C");

t1.start();

t2.start();

t3.start();

}

static class PrintThreadName implements Runnable {

@Override

public void run() {

for (int i = 0; i < 5; i++) {

synchronized (CURRENT_THREAD) {

// 从A开始

while (!CURRENT_THREAD.equals(Thread.currentThread().getName())) {

try {

CURRENT_THREAD.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.print(CURRENT_THREAD);

// 线程打印完毕后,设置下一个要打印的线程标识,并唤醒其他线程

if (CURRENT_THREAD.equals("A")) {

CURRENT_THREAD = "B";

} else if (CURRENT_THREAD.equals("B")) {

CURRENT_THREAD = "C";

} else if (CURRENT_THREAD.equals("C")) {

CURRENT_THREAD = "A";

}

CURRENT_THREAD.notifyAll();

}

}

}

}

}

但是出现了错误

哪个地方出现了问题呢?


回答:

主要的问题是:

// 线程打印完毕后,设置下一个要打印的线程标识,并唤醒其他线程

if (CURRENT_THREAD.equals("A")) {

CURRENT_THREAD = "B";

} else if (CURRENT_THREAD.equals("B")) {

CURRENT_THREAD = "C";

} else if (CURRENT_THREAD.equals("C")) {

CURRENT_THREAD = "A";

}

你使用一个volatile修饰的字符串CURRENT_THREAD来充当锁的角色
但是却在锁对象释放自己拥有的锁之前就把锁的引用给修改了
也就会出现 现在的锁对象其实已经被修改了(它是没有锁的 锁在之前的对象身上)
你还要让它释放锁 属于是强人所难了 所以会报错
这个错误产生的原因是某一线程在等待其他线程释放锁 但是突然要求它释放锁 它还在等呢怎么会有锁 所以就会抛出IllegalMonitorStateException
解决方法就是额外使用另一个锁对象来实现同步 不要在锁对象释放锁之前对它进行任何修改 可以参照楼上的方案


回答:

package 并发编程.work2;

public class Test {

private static final Object lock = new Object();

private static volatile String CURRENT_THREAD = "A";

public static void main(String[] args) {

Thread t1 = new Thread(new PrintThreadName(), "A");

Thread t2 = new Thread(new PrintThreadName(), "B");

Thread t3 = new Thread(new PrintThreadName(), "C");

t1.start();

t2.start();

t3.start();

}

static class PrintThreadName implements Runnable {

@Override

public void run() {

for (int i = 0; i < 5; i++) {

synchronized (lock) {

// 从A开始

while (!CURRENT_THREAD.equals(Thread.currentThread().getName())) {

try {

lock.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.print(CURRENT_THREAD);

// 线程打印完毕后,设置下一个要打印的线程标识,并唤醒其他线程

if (CURRENT_THREAD.equals("A")) {

CURRENT_THREAD = "B";

} else if (CURRENT_THREAD.equals("B")) {

CURRENT_THREAD = "C";

} else if (CURRENT_THREAD.equals("C")) {

CURRENT_THREAD = "A";

}

lock.notifyAll();

}

}

}

}

}

以上是 多线程wait方法报错? 的全部内容, 来源链接: utcz.com/p/945231.html

回到顶部