【发布时间】:2017-05-03 18:24:18
【问题描述】:
我有一个关于同步的“小问题”,这是我的场景(我对同步的了解还不够,我还在学习): (编辑)
Thread work, progress;
final Object myObject;
work = new Thread(() -> {
try {
myObject.doSomething();
} catch (IOException e) {e.printStackTrace();}
});
progress = new Thread(() -> {
while (true) {
System.out.println(myObject.progress());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
work.setDaemon(true);
progress.setDaemon(true);
work.start();
progress.start();
work.join();
progress.interrupt();
progress.join();
/*Other code*/
(编辑:可能已解决)
主作业在WORK线程中完成,作业进度在PROGRESS线程中打印;
这很好用,但我想要一个更好的……“同步”: 唯一的“小”问题是,如果我在 sleep 方法中放了 1 小时,也许工作已经完成,必须等待这 55 分钟才能终止 PROGRESS 线程...... 如何处理这种情况?我希望我的 PROGRESS 线程在工作完成时终止,而不是等待睡眠方法完成。 我想我将不得不使用一些同步块,以及一个 .wait(millis) 调用而不是那个 .sleep(millis) ... 有人可以帮我理解吗?谢谢!
【问题讨论】:
-
如果目标是更新进度系统,您可以考虑将进度更新器传递给工作对象(通过接口),然后让工作人员在进度监视器上调用更新。它是例如 Eclipse 实现进度更新的方式。
-
查看wait/notify/notifyAll,或者
java.util.concurrent(和子包)中更高级的功能。 -
您也可以在工作线程完成时(即在 join() 返回后)简单地中断进度线程。不需要线程不安全的
done数组。 docs.oracle.com/javase/tutorial/essential/concurrency/… -
@MarkRotteveel 我尝试使用带有 .wait(millis) 的等待/通知系统,以便 PROGRESS 线程立即终止,但它没有工作:程序只是进入它遇到的第一个同步块, 没有别的(如果首先达到 WORK 线程同步块,那么我不会从 PROGRESS 中得到任何打印,反之亦然,我只能得到进度的打印,但没有工作)......
-
@JBNizet 我知道,我正在使用该布尔数组来实现等待/通知系统,并使用该值来防止虚假唤醒。
标签: java multithreading synchronization wait