[英]Can a Thread in an ExecutorService call a method on a seperate thread?
[英]while loop in seperate thread continues running after condition has been changed via seperate method in main thread
public void taskInProgress(String jobMessage) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
runningTask = true;
Test:
while (runningTask) {
for (int i = 0; i < runningStars.length; i++) {
System.out.print(runningStars[i].concat(" ").concat(jobMessage));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t.start();
}
public void taskFinnished(String msg) {
this.runningTask = false;
System.out.println("\r".concat(ok(msg)));
}
理想的效果是,星标在控制台中作为无限进度条打印,即嵌套在while
循环中的for
循环,当我调用方法时,星标被状态和消息替换,并且它们停止。 我runningTask
在taskFinnished()
锁定类字段runningTask
来实现这一点。
我的问题是,即使打破了while
循环,星号仍然会打印到控制台上。 即使while
循环条件返回false之后,循环仍会继续执行几秒钟。
屏幕截图:
如此处所示,在taskFinnished()
方法被调用并且while循环中断之后,它仍然说Extracting tar archive
。
这是使用这些实现的代码:
tc.taskInProgress("Extracting tar archive");
// do long operation on main thread, keep console animation running in seperate thread, and return exit int, Unix style
if (exit == 0) {
tc.taskFinnished("Tar finished without errors");
// This breaks the while loop, but more stuff gets printed even after breaking loop
} else {
// failed, handle it
}
尝试更换
for (int i = 0; i < runningStars.length; i++)
与
for (int i = 0; i < runningStars.length && runningTask; i++)
您的布尔标志( runningTask
)必须声明为volatile
。 否则,不能保证正在运行的线程看到主线程所做的更改。
一种替代方法是改用AtomicBoolean。 但是更好的是,您应该使用已经存在的机制来要求线程停止运行:中断线程(通过在其上调用interrupt())。 正在运行的线程将必须使用Thread.currentThread().isInterrupted()
定期检查当前线程是否已被中断。
与自定义布尔标志相比,此机制的优势在于,如果正在运行的线程被阻止等待或休眠,则它将通过抛出InterruptedException而立即退出其等待/休眠状态。
您应该捕获该异常,而不仅仅是在执行过程中忽略它,而应该停止运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.