java - ThreadPoolExecutor 的实现问题

标签 java multithreading applet

我正在使用多个线程将文件上传到服务器。 Java Applet 负责显示 UI。最初我使用 ThreadPoolExecutor 启动 5 个线程并为它们分配 5 个文件。每次上传后,我都会收到来自服务器的通知。当一个线程完成执行时,另一个新线程被分配一个文件,直到所有文件都上传到服务器。

基本代码结构如下:

i> 正在从负责处理上传功能的 Java Applet 调用方法 startUpload()。

class Upload extends Runnable{


...............................
..............................

public void startUpload() {

............................... //other initialisations done

    int waitTime = 500;

    Random random = new Random();

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

    while (it.hasNext()) {

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

                executor.execute(new Runnable() {

                    @Override
                    public void run() {

                       try{
                       Thread.sleep(wait);
                       }
                       catch(Exception e){
                        }
                        processFile1(newFile);
                    }
                });

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

            } catch (Exception e) {
            }

    }

我目前面临的问题。

i> UI 仅在所有文件上传完毕后才更新。在中间阶段,UI 处于挂起状态。 EDT 似乎要进入阻塞状态。

当我使用 Thread 类、通知/ sleep 来实现相同的功能时,用于 UI 渲染的相同代码工作正常。我将代码更改为 ThreadPoolExecutor,因为我在很多博客/文章中看到它是从 Java 5.0 版实现多线程的更好方法。

ii> 我在 ThreadPoolExecutor 中注意到的另一件事是,当我上传大小为 1KB 的多个文件(用于测试目的)时,如果我从上面的代码中删除所有 wait() ,则以下行分配一个新文件但是多个线程每次总是上传同一个文件。

newFile = new File((String) it.next());

但是在添加 sleep() 和 run() 时,多个线程将不同的文件上传到服务器。

上面的代码有实现上的问题吗?

最佳答案

问题 1:newFile 是一个(静态的?)字段而不是局部变量。

你想要的是确保 newFile 的本地捕获在每个循环中都是不同的。因此,它应该看起来更像:

while(it.hasNext()) {
  final File newFile = new File((String) it.next());
  executor.execute(new Runnable() {
    @Override
    public void run() {
      processFile1(newFile); // Local only to this iteration of the loop.
    }
  }
}

您的代码全部包装在 Runnable 实例中。你能告诉我们这是从哪个线程调用的吗?如果它在 EDT 上,那么这就可以解释为什么 UI 会锁定。

一个小问题是您的迭代器缺少泛型。理论上,您应该遍历字符串集合:

Collection<String> listOfFiles = ...

Iterator<String> it = listOfFiles.iterator();

while(it.hasNext()) { 
  String filename = it.next(); // No cast necessary
}

关于java - ThreadPoolExecutor 的实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8075421/

相关文章:

java - 如何在 Windows 上用 Java 创建然后原子地重命名文件?

java - 执行者什么时候真正创建新线程

java - 使用来自 GoDaddy 的 spc 文件签署 java applet

java - 如何将java小程序绑定(bind)到socket?

java - 抛出不需要捕获的异常的方法

java - 在不使用 java 打开浏览器的情况下在浏览器中运行 URL

java - 错误 : non-static variable scan cannot be referenced from a static context in Java

在单独的线程上运行的android服务

java - 线程崩溃

java - 系统记录器是否使用计算机资源?