mar*_*thh 3 java multithreading wait
我有一个线程在我的程序后台运行并检测截止日期(由程序开始时的用户输入设置)何时发生。我已经在while循环中实现了这个并使用了该sleep(1000)方法。
一切正常,但我想将它从使用更改sleep(1000)为使用,wait()并notifyAll()与我的其余代码保持一致,并使警报实时发生,而不是在线程之前滞后一秒重新醒来。
这是我目前拥有的
//Retrieve current date and time...
Calendar now = Calendar.getInstance();
//deadline not yet reached
while(now.before(deadline))
{
try
{
//wait a second and try again
sleep(1000);
}
catch (InterruptedException intEx)
{
//Do nothing.
}
//Update current date and time...
now = Calendar.getInstance();
//run loop again
}
////////////////////////////
///alert user of deadline///
////////////////////////////
Run Code Online (Sandbox Code Playgroud)
我试图将其更改为使用wait(),但没有成功。任何人都可以看到改变现有代码以实现我提到的方法的方法吗?
提前致谢,马克
所以这个问题是,我怎样才能wait像sleep. 如果要使用等待,则必须使用两个线程。使用ScheduledExecutorService(教程)。
ScheduledExecutorService executor = newSingleThreadScheduledExecutor();
Run Code Online (Sandbox Code Playgroud)
这可以完成一次并重复使用。否则,您必须关闭执行程序。
我们将x使用Instant现代java.time框架(教程)将截止日期设置为未来几分钟。
final Instant deadline = Instant.now().plus(x, ChronoUnit.MINUTES);
Run Code Online (Sandbox Code Playgroud)
接下来我们要安排一个任务,以便我们的线程将在 x 分钟内唤醒。
while(Instant.now().isBefore(deadline)){
synchronized(deadline){
executor.schedule(
()->{
synchronized(deadline){
deadline.notifyAll();
}
},
Duration.between(Instant.now(),deadline).toMillis(),
TimeUnit.MILLISECONDS
);
deadline.wait();
}
}
Run Code Online (Sandbox Code Playgroud)
它处于循环中,以防万一出现虚假唤醒。它重新提交任务,以防万一有一个虚假的唤醒,同时另一个任务完成并且在线程再次调用等待之前没有唤醒线程。
这上面是脸颊上的一点舌头。真的,如果您只使用以下内容,它看起来会更“实时”。
long diff = deadline.getTimeInMillis()-now.getTimeInMillis();
if(diff>0)
Thread.sleep(diff);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9733 次 |
| 最近记录: |