更新

我已经更新了这个问题,使用建议的SwingWorker类包含Java实现的源代码,以实现与Objective-C示例相同的结果.希望这将有助于未来的冒险家.

Document myDoc = ...;

Model myModel = ...;

SwingWorker analyzeDocument = new SwingWorker() {

@Override

public Dictionary doInBackground() {

return myDoc.analyze();

}

@Override

public void done() {

try {

stats = get();

myModel.setDict(stats);

myModel.setNeedsDisplay(true);

} catch(InterruptedException ex) {

// log

} catch(ExecutionException ex) {

// log

}

}

};

analyzeDocument.execute();

原帖

在并发编程方面,我缺乏经验,我希望有人能够向我解释如何实现这一目标.

在Objective-C(使用GCD)中,您可以执行以下操作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{

NSDictionary *stats = [myDoc analyze];

dispatch_async(dispatch_get_main_queue(), ^{

[myModel setDict:stats];

[myStatsView setNeedsDisplay:YES];

[stats release];

});

});

此代码将在后台线程中执行[myDoc analyze],在回调函数之后更新将在主线程中执行的UI.换句话说,后台线程向主线程发送一个中断,将匿名函数添加到要调用的主线程队列中.显然我不能在Java中使用匿名函数,但这不是重点.

我有兴趣在Java中做这件事.我有一个Runnable对象,它在文件系统中做了很多东西.完成后,我想相应地更新UI.

为了在执行此操作时不挂起主线程(即:backgroundThread.join();),我设置了后台线程来执行回调函数来更新UI.但这不是一个好主意,我不希望非GUI线程更新GUI.

我想到的其他一些想法是投票,但这似乎是抛出窗口的循环.根据同样的判断,使用期货似乎也不是答案.这一切似乎都打败了异步操作的目的.

我能想到的唯一另一件事是从后台线程使用SwingUtilities.invokeLater并使用它来更新GUI.但我很好奇这将执行哪个线程.

也许我的看法只是扭曲了,但这似乎是一个非常重要的部分.我只是想以错误的方式解决这个问题吗?

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐