我正在根据我需要建立的许多连接生成SwingWorkers。我试图做到这一点,以便我设置一个固定数量的最大的同意SwingWorkers,当其中一个完成另一个启动(或许多其他人启动,如果许多已完成)。基于http://java.dzone.com/articles/multi-threading-java-swing我正在设置基本的SwingWorker,如下所示:
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
System.out.println("One SwingWorker just ran! ");
}
return true;
}
// Can safely update the GUI from this method.
protected void done() {
boolean status;
try {
// Retrieve the return value of doInBackground.
status = get();
statusLabel.setText("Completed with status: " + status);
} catch (InterruptedException e) {
// This is thrown if the thread's interrupted.
} catch (ExecutionException e) {
// This is thrown if we throw an exception
// from doInBackground.
}
}
};
worker.execute();
现在我不确定如何实现上述机制。
从https://stackoverflow.com/a/8356896/988591我看到我可以使用ExecutorService来执行SwingWorker的实例,并且该接口还允许设置线程数:
int n = 20; // Maximum number of threads
ExecutorService threadPool = Executors.newFixedThreadPool(n);
SwingWorker w; //don*t forget to initialize
threadPool.submit(w);
我认为这就是我的需要,但我不知道如何把整个事情放在一起(..我对Java也很新......)。有人可以在实施过程中指导我一点吗?在顶部说我有int totalTask = 100;
也许它只是一些循环的问题,但我似乎无法找到任何真正易于理解的例子,我只是不能完全包裹着我的思绪然而......我会感激一些帮助!感谢。
更新:我已经以这种方式设置了ExecutorService:
ExecutorService executorService = Executors.newFixedThreadPool(500);
for (int i = 0; i < 20 ; i++) {
executorService.submit(worker);
//I tried both...
//executorService.execute(worker);
}
我已经删除了上面的SwingWorker之后调用的worker.execute()
,但是控制台的输出只是一个&#34; One SwingWorker刚刚运行!&#34; 行,这是怎么回事?我做错了什么?
答案 0 :(得分:1)
您可以这样做:
像这样:
ExecutorService executorService = Executors.newFixedThreadPool(500);
for (long i = 0; i < 1000000; i++) {
Runnable populator = new YourRunnable();
executorService.execute(populator);
}
executorService.shutdown();
while(!executorService.isTerminated()){
}
thatTerminated可用于检查executorServices是否实际关闭。由于即使在调用shutdown()方法之后也可以运行多个执行程序线程(因为它们尚未完成任务),因此while循环就像一个等待调用。
一个关键的事情是:无论你想传递给ExecutorService,它都必须是一个Runnable实现。在您的情况下,您的SwingWorker必须是Runnable。
答案 1 :(得分:1)
这很有意思。使用具有有限池的ExecutorService,您只需要随时提交工作人员,并且只会同时执行这些工作量。
我制作了这个小测试应用程序,您可以按下按钮提交一些工作人员,并且您可以查看在任何给定时间执行的工作量从不高于值{{1你使用。
初始化了ExecutorServicenumberOfThreads
看起来像这样:
例如,如果您提交了大量工作人员,那么如果您提交了大量工作人员,那么如果您提交了大量工作人员,则需要一次执行2个工作线程。
答案 2 :(得分:0)
请查看SwingWorker的源代码。 你可以类似于execute()方法
public final void execute() {
getWorkersExecutorService().execute(this);
}
此时,您可以创建一个ExecutorService并管理池
SwingWorker<Boolean, Void> test = new SwingWorker<Boolean, Void>() {
private ExecutorService service = new ThreadPoolExecutor(5, 10,
10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(),
new ThreadFactory() {
AtomicInteger count= new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread("Pooled SwingWorker " + count.getAndAdd(1));
}
});
@Override
protected Boolean doInBackground() throws Exception {
return true;
}
public void doIt() {
service.execute(this);
}
};
答案 3 :(得分:0)
你想的那一刻: 这是显而易见的!
ExecutorService executorService = Executors.newFixedThreadPool(20);
for (int i = 0; i < 500; i++) {
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
System.out.println("One SwingWorker just ran!");
return true;
}
protected void done() {
boolean status;
try {
status = get();
} catch (InterruptedException e) {
// This is thrown if the thread's interrupted.
} catch (ExecutionException e) {
// This is thrown if we throw an exception
// from doInBackground.
}
}
};
executorService.submit(worker);
}
它很棒!