我一直是用Java处理图像的程序。然而,在该图像处理期间,同时运行的摆动GUI(并且包括进度条等)简单地冻结直到处理完成。我已经尝试多线程程序来解决这个问题,让处理在后台运行,但它似乎不起作用。
以下是我一直在使用的一些代码。
public class GUIThread implements Runnable {
public static final int CHOOSER_HUB = 0;
public static final int LAUNCH_IMAGE_PREVIEWER = 1;
public static final int DISABLE_PREVIEWER_BUTTONS = 2;
public static final int MEMORY_USAGE_WINDOW = 3;
private int guiNumber;
// ==========================================================================
// | START CODE |
// ==========================================================================
/**
* Runs begins the thread. This method is also for pre-run configuration,
* but so far there is none of that.
*
* @param GUINumber
* The GUI number, indicating which GUI to start.
*/
public void start(int GUINumber) {
DebugMessenger.out("Starting new thread for GUI");
guiNumber = GUINumber;
run();
}
/**
* Starts the thread, and runs a method determined by what guiNumber was set.
*/
@Override
public void run() {
DebugMessenger.out("Thread running");
if (guiNumber == GUIThread.CHOOSER_HUB)
createChooserHub();
if (guiNumber == GUIThread.LAUNCH_IMAGE_PREVIEWER)
createPreviewer();
if (guiNumber == GUIThread.DISABLE_PREVIEWER_BUTTONS)
disablePreviewerButtons();
if (guiNumber == GUIThread.MEMORY_USAGE_WINDOW)
createMemoryUsageWindow();
}
/* More code, including methods called by run() */
}
要启动我的程序,我只需运行以下代码。
public class Main {
/**
* Main method. Starts the threads and lets them roll.
* @param args
*/
public static void main(String[] args) {
// start threads
DebugMessenger.out("Starting Main");
GUIThread guiThread = new GUIThread();
guiThread.start(GUIThread.LAUNCH_IMAGE_PREVIEWER);
if(Config.DEBUG_OUTPUT_ENABLED) {
memBarThread = new GUIThread();
memBarThread.start(GUIThread.MEMORY_USAGE_WINDOW);
}
DebugMessenger.out("Main complete");
}
}
正如您所看到的,我使多线程尽可能简单,但似乎当我运行程序并且图像预览器开始处理时,内存使用窗口会冻结。我该如何防止这种情况?
答案 0 :(得分:0)
您在代码中遗漏的一个重要问题是,在Java中,您永远不会自己调用run
()(如果您这样做,它将不会创建单独的线程,而不是它将在主线程中运行),而是你将创建一个Thread
对象并启动Thread
(使用如下所示的start方法),以便它将调用{{1单个线程中的()方法,如下所示:
GUIThread类:
run
主要类别:
public class GUIThread implements Runnable {
public static final int CHOOSER_HUB = 0;
public static final int LAUNCH_IMAGE_PREVIEWER = 1;
public static final int DISABLE_PREVIEWER_BUTTONS = 2;
public static final int MEMORY_USAGE_WINDOW = 3;
private int guiNumber;
public void setGUINumber(int GUINumber) {
this.guiNumber = GUINumber;
}
@Override
public void run() {
DebugMessenger.out("Thread running");
if (guiNumber == GUIThread.CHOOSER_HUB)
createChooserHub();
if (guiNumber == GUIThread.LAUNCH_IMAGE_PREVIEWER)
createPreviewer();
if (guiNumber == GUIThread.DISABLE_PREVIEWER_BUTTONS)
disablePreviewerButtons();
if (guiNumber == GUIThread.MEMORY_USAGE_WINDOW)
createMemoryUsageWindow();
}
/* More code, including methods called by run() */
}
您可以查看here
答案 1 :(得分:0)
您根本没有使用多线程来使用您提供的代码。
首先调用GUIThread.start(int)
,无论输入此调用run()
,我猜这是阻塞工作的方法。无处创建新线程并告知它开始独立执行。
我建议您研究以下概念:
答案 2 :(得分:0)
您的GUI冻结,因为操作仍在Swing GUI线程中运行。
让GUIThread类扩展Thread
(而不是实现Runnable
)并调用Thread的start
方法。