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