Java 在不使事件调度线程等待的情况下渲染图像?
我在多个线程上渲染一个BuffereImage。当我启动这些线程时,我正在调用事件调度线程上的wait,以便它仅在所有渲染线程都发送了notify信号时才实际绘制图像 这就是EDT中发生的情况:Java 在不使事件调度线程等待的情况下渲染图像?,java,multithreading,concurrency,event-dispatch-thread,Java,Multithreading,Concurrency,Event Dispatch Thread,我在多个线程上渲染一个BuffereImage。当我启动这些线程时,我正在调用事件调度线程上的wait,以便它仅在所有渲染线程都发送了notify信号时才实际绘制图像 这就是EDT中发生的情况: synchronized (this) { while(threadsCompleted<RENDERING_THREADS){ try{ this.wait(); }catch (Interr
synchronized (this)
{
while(threadsCompleted<RENDERING_THREADS){
try{
this.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
threadsCompleted = 0;
}
g2.drawImage(image);
我的问题是:有没有一种方法可以让对drawImage的调用等待线程完成,而不实际停止EDT工作?有没有一种方法可以让用户在渲染进行的毫秒内与UI进行交互,从而事件调度线程?最简单的方法是使用
java.util.concurrent
中的并发结构,并使用等待所有其他线程完成的线程,如下所示:
public class ImageRenderer implements Runnable
{
private final CountDownLatch latch;
public ImageRenderer(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try
{
// code...
} finally
{
latch.countDown();
}
}
}
public class Waiter implements Runnable
{
private final CountDownLatch latch;
public Waiter(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try
{
latch.await();
// rendering has now finished.
SwingUtilities.invokeLater(() -> {
// do something with the image on the EDT
}
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
将\第一个同步代码移动到它自己的线程中,并使用SwingUtilities invokeLater Runnable run方法调用drawImage方法。
public class ImageRenderer implements Runnable
{
private final CountDownLatch latch;
public ImageRenderer(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try
{
// code...
} finally
{
latch.countDown();
}
}
}
public class Waiter implements Runnable
{
private final CountDownLatch latch;
public Waiter(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try
{
latch.await();
// rendering has now finished.
SwingUtilities.invokeLater(() -> {
// do something with the image on the EDT
}
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}