[英]Multithreading in java (two threads extensively using both notify() and wait())
当我尝试运行以下程序时,在这段代码中的第一个通知()的调用中有一个IllegalMonitorStateException:
synchronized (c) {
try {
notify();
....
这让我有些不安:如果代码(c)已经在同步块中并检查了相同的锁,那么该代码怎么可能没有对它锁?
请不要介意对notify()和wait()的使用有些奇怪。 我知道有多种执行相同任务的(更有效的)实现方式,但是现在我试图弄清楚为什么这个特定的方式行不通。
完整的代码如下:
class J implements Runnable {
public static void main(String[] x) {
Calc calc = new Calc();
J j = new J(calc);
Thread t1 = new Thread(j, "one");
Thread tCalc = new Thread(calc, "Calc");
tCalc.start();
t1.start();
}
Calc c;
public J(Calc c) {
this.c = c;
}
public void run() {
synchronized (c) {
try {
notify();
c.wait();
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + ": x = "
+ c.getX());
notify();
}
}
}
class Calc implements Runnable {
private int x;
public int getX() {
return x;
}
public void run() {
synchronized (this) {
for (int x = 1; x <= 11111; x *= (x + x)) {
this.x += x;
try {
notify();
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
您正在尝试通知线程正在等待您当前未持有的其他锁。 该错误是合理的。 您在对象c上有一个锁,然后将当前对象上的锁通知其他线程。
synchronized (c) {
try {
notify();
....
您正在锁定对象c
但是正在通知对象this
。 最好始终在将来明确指定要在哪个对象上使用wait()
或notify()
。 你应该做:
synchronized (c) {
try {
c.notify();
....
要么:
synchronized (this) {
try {
this.notify();
....
看来您实际上要处理2个锁。 如果是这种情况,则可以执行以下操作。
synchronized (c) {
try {
synchronized (this) {
this.notify();
}
c.wait();
以确保您始终锁定是很重要的c
第一,然后this
,否则你就会死锁。
您拥有的是执行以下操作的复杂方法。
ExecutorService printer = Executors.newSingleThreadExecutor();
int x2 = 0;
for (int x = 1; x <= 11111; x *= (x + x)) {
x2 += x;
final int x3 = x2;
printer.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": x = " + x3);
}
});
}
printer.shutdown();
如果您不尝试使用两个线程来完成比一个线程更快/更简单的操作,这将更加简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.