gpt4 book ai didi

java - 正确使用ProgressMonitorDialog的取消按钮、中断线程、显示进度

转载 作者:行者123 更新时间:2023-11-30 08:03:07 25 4
gpt4 key购买 nike

我已经使用Java几年了,但我的线程知识很垃圾。我在 Google 上进行了大量搜索,发现了一些有关 ProgressMonitorDialog 一般使用的好信息,但与我的具体情况完全不同。

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

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

这是我迄今为止得到的代码的精炼版本。

数据:

public class Data {
public static Thread createThread() {
return new Thread() {
@Override
public void run() {
Thing t = new Thing();
t.operationA();
t.operationB();
t.operationC();
}
}
}
}

用户界面:

public class UI {

public void doOperation() {
try {
new ProgressMonitorDialog(getShell()).run(true, true, new MyOperation());
}
catch (Exception e) {
e.printStatckTrace();
}
}

public class MyOperation implements IRunnableWithProgress {

@Override
public void run(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {

monitor.beginTask("Task", 2);

try {
Thread myThread = Data.createThread();
myThread.start();
monitor.worked(1);

while (myThread.isAlive() && !monitor.isCanceled()) {}

if (monitor.isCanceled()) {
myThread.interrupt();
}

monitor.worked(1);

}
finally {
monitor.done();
}
}
}

}

因此,当单击取消按钮时,将调用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;
}
}
}
}

像这样轮询中断状态可能会相当冗长,但我看不出这会导致任何问题。

但是,如果 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(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 将实例化它并将其传递给线程。这样,数据就可以将进度事件传递到 UI,而无需依赖。

关于java - 正确使用ProgressMonitorDialog的取消按钮、中断线程、显示进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31584412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com