我正在使用多个线程将文件上传到服务器。 Java Applet负责显示UI。最初,我使用ThreadPoolExecutor启动5个线程,并为其分配5个文件。每次上传后,我都会从服务器收到通知。当线程完成执行时,将为另一个新线程分配一个文件,直到所有文件都上载到服务器。
基本代码结构如下:
从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类时,相同的UI呈现代码工作正常,notify/sleep实现相同的功能。我将代码更改为ThreadPoolExecutor,因为在任何博客/文章中都没有看到它是从Java ver 5.0实现多线程的更好方法。
ii>我在使用ThreadPoolExecutor注意到的另一件事是,当我上传多个大小为1KB的文件(出于测试目的)时,如果我从上述代码中删除了所有的wait(),则以下行分配了一个新文件,但相同文件总是每次都由多个线程上载。
newFile =新文件((String)it.next());
但是,在与run()一起添加sleep()时,多个线程将不同的文件上传到服务器。
上面的代码有实现问题吗?
最佳答案
问题1:newFile
是一个(static?)字段,而不是局部变量。
您要确保每个循环的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/