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)));
}
希望的效果是,星星在控制台中打印为无限进度条,即嵌套在for
循环中的while
循环,当我调用方法时,星星得到替换为状态和消息,他们被停止。我通过锁定runningTask
中的类字段taskFinnished()
来实现此目的。
我的问题是,即使在打破while
循环后,星星仍会打印到控制台。即使在while
循环条件返回false之后,循环仍继续执行,持续几秒钟。
截图:
如此处所示,在调用Extracting tar archive
方法并且while循环中断后,它仍然显示taskFinnished()
。
以下是使用这些实现的代码:
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
}
答案 0 :(得分:1)
尝试替换
for (int i = 0; i < runningStars.length; i++)
与
for (int i = 0; i < runningStars.length && runningTask; i++)
答案 1 :(得分:0)
您的布尔标志(runningTask
)必须声明为volatile
。否则,无法保证正在运行的线程看到主线程所做的更改。
另一种方法是使用AtomicBoolean。但更好的是,你应该使用已经存在的机制来要求线程停止运行:中断线程(通过调用它上面的interrupt())。正在运行的线程必须使用Thread.currentThread().isInterrupted()
定期检查当前线程是否已被中断。
这种机制优于自定义布尔标志的优点是,正在运行的线程被阻塞等待或休眠,它将立即通过抛出InterruptedException而退出其等待/休眠状态。
你应该抓住那个例外,但不要像你一样忽略它,而应该尽快停止运行。