使用ThreadPoolExecutor时的UI问题

时间:2011-11-09 09:25:15

标签: java multithreading applet

我使用ThreadPoolExecutor来实现多线程。

基本上每个线程都分配了一个文件,需要将其上传到服务器。 每次成功上传后,都会从服务器发出通知。

以下代码生成线程&将文件分配给他们。

Random random = new Random();
              ExecutorService executor = new ThreadPoolExecutor(5, 5, 50000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(400));

        int waitTime = 100;
        while (it.hasNext()) {

            int time = random.nextInt(1000);
            waitTime += time;
            newFile = new File((String) it.next());
            executor.execute(new Runnable() {

                @Override
                public void run() {

                    processFile(newFile);
                }
            });
            try {
                Thread.sleep(waitTime);
            } catch (Exception e) {
            }

        }

        try {
            Thread.sleep(waitTime);
            executor.shutdown();
            executor.awaitTermination(waitTime, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
        }

我创建了一个用于呈现UI的Java Applet。 在每次通知之后,我将在Java Applet窗口中更新文件状态,其中从processFile()调用updateUI()。

在使用ExecutorService之前(建议在Java v5.0和上面处理多线程),我使用Thread类创建线程&amp; wait-notify用于文件上载功能。显示每个文件更新状态的UI使用Thread类正确呈现,但在使用ExecutorService时,所有文件都上传(功能正常)但UI挂起。

成功上传每个文件后,需要更新每个文件的文件上载状态。

欢迎任何建议/提示。

1 个答案:

答案 0 :(得分:0)

当想要从非EDT线程(调用事件处理程序的事件线程等)更新UI时,您需要使用SwingUtilities.invokeLater(Runnable)

你不应该在EDT上睡觉或阻止它,因为那是确保一切都响应的那个

然而,最好使用SwingWorker,因为这会实现特定于使用需要更新gui的后台线程的几件事

使用swingWorker,您的代码将是

while (it.hasNext()) {

    final File newFile = new File((String) it.next());
    SwingWorker<Void,Void> work = new SwingWorker<Void,Void>(){

        @Override
        public Void doInBackground() {

            processFile(newFile);//do **not** call updateUI() in here
            return null;
        }

        @Override
        protected void done(){//this gets called after processFile is done on the EDT
            updateUI();
        }
    }).execute();
}