Java 正确使用ProgressMonitorDialog';单击“取消”按钮,中断线程并显示进度

Java 正确使用ProgressMonitorDialog';单击“取消”按钮,中断线程并显示进度,java,multithreading,eclipse-rcp,interrupt,java-threads,Java,Multithreading,Eclipse Rcp,Interrupt,Java Threads,我已经使用Java好几年了,但是我的线程知识是垃圾。我在谷歌上搜索了很多,找到了一些关于ProgressMonitorDialog一般用法的好信息,但与我的实际情况完全不同 我目前正在使用ProgressMonitorDialog作为irunablewithprogress实例的包装器,而该实例又是线程的包装器。这很好,但现在我试图让cancel按钮触发运行线程上的中断,我可以处理该中断以优雅地终止操作 需要注意的一点是,我有两个插件;“数据”和“用户界面”。数据插件包含所有实际工作,并且必须独

我已经使用Java好几年了,但是我的线程知识是垃圾。我在谷歌上搜索了很多,找到了一些关于
ProgressMonitorDialog
一般用法的好信息,但与我的实际情况完全不同

我目前正在使用
ProgressMonitorDialog
作为
irunablewithprogress
实例的包装器,而该实例又是
线程的包装器。这很好,但现在我试图让cancel按钮触发运行线程上的中断,我可以处理该中断以优雅地终止操作

需要注意的一点是,我有两个插件;“数据”和“用户界面”。数据插件包含所有实际工作,并且必须独立于UI或任何Eclipse插件。UI插件应该尽可能薄

这是我到目前为止得到的代码的一个提炼版本

数据:

用户界面:

因此,当单击“取消”按钮时,将调用myThread.interrupt()
。现在线程需要响应中断
Data.createThread()
现在看起来像这样:

public static Thread createThread() {
    return new Thread() {
        @Override
        public void run() {

            Thing t = new Thing();

            t.operationA();

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationB();

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationC();

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }
        }
    }
}
public static Thread createThread() {
    return new Thread() {
        @Override
        public void run(IProgressMonitor monitor) {

            Thing t = new Thing();

            t.operationA();

            monitor.worked(1);

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationB();

            monitor.worked(1);

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationC();

            monitor.worked(1);

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }
        }
    }
}
像这样轮询中断状态可能相当冗长,但我看不出这会导致任何问题

但是,如果
Thing.operationA()
不是原子的,并且可能在该函数中被中断,该怎么办

public class Thing {
    public void operationA() {
        atomic1();
        // How would I detect and handle a change to the interrupted state here?
        atomic2();
    }
    public void operationB() {
        // One atomic operation
    }
    public void operationC() {
        // One atomic operation
    }
}
如何检测和处理
atomic1()
atomic2()
之间中断状态的更改?它是否像轮询Thread.currentThread.isInterrupted()一样简单?或者我需要传递一些
volatile
对象来跟踪中断状态吗?我应该在某个地方抛出
InterruptedException

我的第二个问题是关于跟踪和报告进展情况。我理解应该如何使用
IProgressMonitor.worked()
。如前所述,我的数据线程包含3个操作。是否可以将该信息传递到UI,以便我可以在
ProgressMonitorDialog
中跟踪进度

理想情况下,类似这样的情况:

public static Thread createThread() {
    return new Thread() {
        @Override
        public void run() {

            Thing t = new Thing();

            t.operationA();

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationB();

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationC();

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }
        }
    }
}
public static Thread createThread() {
    return new Thread() {
        @Override
        public void run(IProgressMonitor monitor) {

            Thing t = new Thing();

            t.operationA();

            monitor.worked(1);

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationB();

            monitor.worked(1);

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }

            t.operationC();

            monitor.worked(1);

            if (Thread.currentThread.isInterrupted()) {
                // Tidy up
                return;
            }
        }
    }
}
但是如上所述,数据不能依赖于Eclipse,因此在这种情况下传递
IProgressMonitor
不起作用

我可以在我的线程中有一个跟踪进度的变量,然后从UI线程异步调用类似于
myThread.getProgress()
的东西,用新的工作更新进度条吗?我不确定这是否可行(当我写这个问题时,它突然出现在我的脑海中),所以我下一步会尝试

这里有很多信息和问号,如果我的风格有点分散的话,很抱歉。如果需要的话,我可以详细说明,但这已经是一堵文字墙了。感谢您提供的任何信息、建议或想法。

atomic1()
atomic2()
之间,您确实需要检查
Thread.currentThread.isInterrupted()
以进行清除,以防取消。如果处理了所需的内容,则无需抛出异常


至于进度跟踪,您可以在数据插件中创建自己的侦听器对象,并允许将其传递给线程。UI将实例化它并将其传递给线程。通过这种方式,数据可以将进度事件传递到用户界面,而无需依赖项。

谢谢,这是有用的信息。使用侦听器跟踪进度是一个好主意!