在我的Processing应用程序中,我监听鼠标点击,然后在按钮类中处理它们。然后button类通过调用setScreenIndex设置正确的内容。该函数检测这是否是第一次加载屏幕,然后设置它(在示例化时不设置,因此如果用户不需要不必要的屏幕,则不加载它们)。设置是通过调用设置函数的线程完成的。然而,当鼠标忙碌时再次单击鼠标时,此线程似乎会中断。这会导致加载屏幕无限期地显示(线程仍然注册为活动,即使它不再执行任何操作),或者加载屏幕完全冻结。我相信这是一个线程问题,有些东西交互奇怪,但我迷路了,已经花了一个星期在这个问题上。相关代码如下:
final class Main
{
public synchronized void update()
{
try
{
if (threadToWaitFor != null)
{
if (!threadToWaitFor.isAlive())
{
threadToWaitFor = null;
setScreenIndex(nextScreenIndex);
}
}
currentScreen.update();
}
catch (Exception e)
{
logger.println("ERROR: Main Update: " + e.getMessage());
logger.println("Stack Trace: ");
e.printStackTrace(logger);
logger.flush();
exit();
}
}
public synchronized void setScreenIndex(int screenIndex)
{
this.screenIndex = screenIndex;
currentScreen = screens.get(this.screenIndex);
if (!currentScreen.getSetup())
{
SetupScreenThread thread = new SetupScreenThread(currentScreen);
thread.start();
waitForThread(thread, screenIndex);
}
}
public synchronized void waitForThread(Thread thread, int newScreenIndex)
{
this.threadToWaitFor = thread;
this.nextScreenIndex = newScreenIndex;
this.currentScreen = loadScreen;
}
}
我试过使用synchronised和volatile关键字检查按钮没有被调用两次,并且没有同时调用相同的函数,但这没有帮助。如果您没有多次单击,则一切正常,并且行为/加载正确。我试过在主类中实现一个锁,这样如果标志设置为忙碌,单击甚至不会到达主类,但这也不起作用。
1条答案
按热度按时间fnx2tebb1#
我认为你解决问题的方法是错误的。
您正在尝试实现视图的延迟加载,这是一个好主意。但试图自己实现这一点并不是一个好主意。
您应该使用已经存在的允许异步计算的类。未来API是您的盟友。
这个代码并不意味着是完美的。只是为了给予您了解如何将Future API用于您的用例。