与 ThreadPoolExecutor 的线程同步
当我创建主(父)线程并执行其他几个线程时,我试图实现一些逻辑。然后它等待子线程创建的某些条件。条件满足后,父亲执行更多的子线程。 当我使用 wait/notify 时出现 java.lang.IllegalMonitorStateException 异常的问题。这是代码:
public class MyExecutor {
final static ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10);
final static ExecutorService svc = Executors.newFixedThreadPool(1);
static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 8, 10, TimeUnit.SECONDS, queue);
public static void main(String[] args) throws InterruptedException {
final MyExecutor me = new MyExecutor();
svc.execute(new Runnable() {
public void run() {
try {
System.out.println("Main Thread");
me.execute(threadPool, 1);
System.out.println("Main Thread waiting");
wait();
System.out.println("Main Thread notified");
me.execute(threadPool, 2);
Thread.sleep(100);
threadPool.shutdown();
threadPool.awaitTermination(20000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
svc.shutdown();
svc.awaitTermination(10000, TimeUnit.SECONDS);
System.out.println("Main Thread finished");
}
public void execute(ThreadPoolExecutor tpe, final int id) {
tpe.execute(new Runnable() {
public void run() {
try {
System.out.println("Child Thread " + id);
Thread.sleep(2000);
System.out.println("Child Thread " + id + " finished");
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
当我注释 wait 和 notification 行时,我有以下输出:
主线程
主线程等待
主线程已通知
子线程 1
子线程 2
子线程 1 已完成
子线程 2 已完成
主线程完成
I'm trying to implement some logic when I create main(father) thread witch executes several other threads. Then it waits for some condition which child threads creates. After condition is meet the father executes some more child threads.
The problem that when I use wait/notify I have java.lang.IllegalMonitorStateException exception. Here is the code:
public class MyExecutor {
final static ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10);
final static ExecutorService svc = Executors.newFixedThreadPool(1);
static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 8, 10, TimeUnit.SECONDS, queue);
public static void main(String[] args) throws InterruptedException {
final MyExecutor me = new MyExecutor();
svc.execute(new Runnable() {
public void run() {
try {
System.out.println("Main Thread");
me.execute(threadPool, 1);
System.out.println("Main Thread waiting");
wait();
System.out.println("Main Thread notified");
me.execute(threadPool, 2);
Thread.sleep(100);
threadPool.shutdown();
threadPool.awaitTermination(20000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
svc.shutdown();
svc.awaitTermination(10000, TimeUnit.SECONDS);
System.out.println("Main Thread finished");
}
public void execute(ThreadPoolExecutor tpe, final int id) {
tpe.execute(new Runnable() {
public void run() {
try {
System.out.println("Child Thread " + id);
Thread.sleep(2000);
System.out.println("Child Thread " + id + " finished");
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
When I comment wait and notify line I have the following output:
Main Thread
Main Thread waiting
Main Thread notified
Child Thread 1
Child Thread 2
Child Thread 1 finished
Child Thread 2 finished
Main Thread finished
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码中存在一系列设计缺陷:
是对象锁的所有者时,才必须调用
wait()
和notify()
:只有当您 在不同的对象(内部类!)上调用
wait()
和notify()
- 如果一个线程正在等待一个对象,则必须调用notify同一个对象上的代码>。
此方法时,有可能会错过
notify
当在
wait
之前调用- 非常 严重错误(竞争条件可能性)。其他人可能建议您使用一些更高级别的同步方法,但了解基础知识至关重要。
There is a series of design flaws in your code:
Calling both
wait()
andnotify()
must occur only when you are the owner of the lock of the object:You are calling
wait()
andnotify()
on different objects (inner classes!) - if one threads is waiting on one object, you must callnotify
on the same object.There is a possibility of missed
notify
when this:is called before
wait
- very serious bug (race condition possibility).Others might suggest you using some higher level synchronization methods, but it is crucial to understand the basics.