Jea*_*ves 7 java multithreading java.util.concurrent
我有一个用例来自GUI问题,我想提交给你的睿智.
用例
我有一个GUI,根据用户在GUI中设置的一些参数显示计算结果.例如,当用户移动滑块时,会触发几个事件,这些事件都会触发新的计算.当用户将滑块值从A调整为B时,会触发数十个事件.
但是计算可能需要几秒钟,而滑块调整可以每隔几百毫秒触发一次事件.
如何编写一个能够监听这些事件的正确线程,并对它们进行过滤以使结果的重绘更加生动?理想情况下,你会喜欢这样的东西
我试过了什么
我的一个朋友(A. Cardona)提出了一种更新程序线程的低级方法,可以防止太多事件触发计算.我在这里复制粘贴(GPL):
他把它放在一个扩展Thread的类中:
public void doUpdate() {
if (isInterrupted())
return;
synchronized (this) {
request++;
notify();
}
}
public void quit() {
interrupt();
synchronized (this) {
notify();
}
}
public void run() {
while (!isInterrupted()) {
try {
final long r;
synchronized (this) {
r = request;
}
// Call refreshable update from this thread
if (r > 0)
refresh(); // Will trigger re-computation
synchronized (this) {
if (r == request) {
request = 0; // reset
wait();
}
// else loop through to update again
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void refresh() {
// Execute computation and paint it
...
}
Run Code Online (Sandbox Code Playgroud)
每当GUI发送一个事件表明参数已被更改时,我们就会调用updater.doUpdate().这导致方法refresh()被调用得更少.但我无法控制这一点.
其他方式?
我想知道是否有另一种方法可以使用jaca.concurrent类.但我无法在Executors框架中排序我应该开始的那个.
你们中有没有一些类似用例的经验?
谢谢
如果您正在使用Swing,则SwingWorker提供了这方面的功能,并且您不必自己处理线程池。
SwingWorker为每个请求触发一个。如果有新的请求进来,而工作人员还没有完成,你可以cancel(),然后开始一个新的SwingWorker. 关于另一张海报所说的,我不认为publish()并且process()是您正在寻找的(尽管它们也非常有用),因为它们适用于工作人员可能比 GUI 处理事件的速度更快的情况。
ThingyWorker worker;
public void actionPerformed(ActionEvent e) {
if( worker != null ) worker.cancel();
worker = new ThingyWorker();
worker.execute();
}
class ThingyWorker extends SwingWorker<YOURCLASS, Object> {
@Override protected YOURCLASS doInBackground() throws Exception {
return doSomeComputation(); // Should be interruptible
}
@Override protected void done() {
worker = null; // Reset the reference to worker
YOURCLASS data;
try {
data = get();
} catch (Exception e) {
// May be InterruptedException or ExecutionException
e.printStackTrace();
return;
}
// Do something with data
}
}
Run Code Online (Sandbox Code Playgroud)
动作和done()方法都在同一个线程上执行,因此它们可以有效地检查引用是否存在现有的worker。
请注意,实际上,这与允许 GUI 取消现有操作的操作相同,只不过取消是在触发新请求时自动完成的。
| 归档时间: |
|
| 查看次数: |
1337 次 |
| 最近记录: |