繁体   English   中英

通过主线程中的单独方法更改条件后,单独线程中的循环继续运行

[英]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循环,当我调用方法时,星标被状态和消息替换,并且它们停止。 runningTasktaskFinnished()锁定类字段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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM