gpt4 book ai didi

java使用线程来避免GUI死锁

转载 作者:行者123 更新时间:2023-11-30 02:59:28 25 4
gpt4 key购买 nike

我有一个项目,根据用户输入在 Canvas 上绘制复杂的表单。

现在,计算和绘制表单需要相当长的时间,因此我将计算和绘制放在不同的线程上:

首先,我计算所有边缘,然后将它们绘制到单独的 Canvas 上,然后将内容从单独的 Canvas 复制到屏幕 Canvas 。

计算代码

// Make 3 new threads. each thread calculates an edge.
Thread thread1 = new Thread(new RunnableClass("L", nxt, edges, application));
Thread thread2 = new Thread(new RunnableClass("R", nxt, edges, application));
Thread thread3 = new Thread(new RunnableClass("B", nxt, edges, application));

thread1.start();
thread2.start();
thread3.start();

// The code waits here until all Threads are finished.
try
{
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException ex)
{
Logger.getLogger(KochManager.class.getName()).log(Level.SEVERE, null, ex);
}

然后我用默认代码(使用 GraphicsContext)绘制它,该代码可以工作,所以我不会在这里复制它。

然后我将内容复制到屏幕上:

SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
WritableImage image = hiddenCanvas.snapshot(params, null);
kochPanel.getGraphicsContext2D().drawImage(image, 0, 0);

但我的问题是:无论我如何尝试,我总是会导致主线程死锁:如果我使用 join(),它将等待线程结束。于是我想:我可以使用一个计时器来检查线程是否像这样完成:

timer.scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
{
if (running == false) {
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
WritableImage image = hiddenCanvas.snapshot(params, null);
kochPanel.getGraphicsContext2D().drawImage(image, 0, 0);
application.setTextCalc( String.valueOf(timeStampCalc.toString()));
application.setTextDraw(timeStampDraw.toString());
application.setTextNrEdges(String.valueOf(kf.getNrOfEdges()));
}
}

}, 0, 250);

就在那时我发现计时器也在一个单独的线程上。

所以我的问题是:如何确保我等待绘制到 Canvas ,直到所有线程完成其工作,而不阻塞/死锁主线程?

下面只是 GUI 外观的示例,以便您有个想法。 First example

2nd example

最佳答案

如果不想使用join,可以使用监视器来控制线程执行

class ThreadJoiner`
{
private int numThreads;
private int finishedThreads;

public ThreadJoiner(int numThreads)
{
this.numThreads = numThreads;
}

public synchronized void updateFinishedThread() throws Exception
{
this.finishedThreads++;
notify();
}

public synchronized void awaitThreads() throws Exception
{
while(this.finishedThreads < this.numThreads)
wait();
}
}

您可以使用要启动的线程数构造此对象。当每个线程完成时,它将调用 updateFinishedThread() 。主线程应在启动计算线程后调用 awaitThreads()

关于java使用线程来避免GUI死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36318207/

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