Java 如何正确使用ExecutorService来管理并发运行的SwingWorker的数量?
我正在根据我需要建立的大量连接生成SwingWorkers。我正试图做到这一点,以便我设置一个固定数量的最大concurrant Swingworker,当其中一个完成时,另一个启动(或者如果许多人已经完成,则启动许多其他人)。基于此,我正在设置如下基本SwingWorker:Java 如何正确使用ExecutorService来管理并发运行的SwingWorker的数量?,java,swing,threadpool,executorservice,swingworker,Java,Swing,Threadpool,Executorservice,Swingworker,我正在根据我需要建立的大量连接生成SwingWorkers。我正试图做到这一点,以便我设置一个固定数量的最大concurrant Swingworker,当其中一个完成时,另一个启动(或者如果许多人已经完成,则启动许多其他人)。基于此,我正在设置如下基本SwingWorker: SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { @Override p
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();
我想这就是我所需要的,但我不知道如何把整个事情放在一起(……我对Java也很陌生……)。在实施过程中,有人能给我一些指导吗?在顶部说我有inttotaltask=100代码>也许这只是一些循环的问题,但我似乎找不到任何真正容易理解的例子,我只是还不能完全理解它,所以。。我会很感激你的帮助!谢谢
更新:我已通过以下方式设置Executor服务:
ExecutorService executorService = Executors.newFixedThreadPool(500);
for (int i = 0; i < 20 ; i++) {
executorService.submit(worker);
//I tried both...
//executorService.execute(worker);
}
ExecutorService ExecutorService=Executors.newFixedThreadPool(500);
对于(int i=0;i<20;i++){
执行者服务。提交(工人);
//我两个都试过了。。。
//executorService.execute(工人);
}
我已经删除了在上面SwingWorker之后调用的worker.execute()
,但是控制台的输出只是一行“一个SwingWorker刚刚运行!”,这是怎么回事?我做错了什么?请看一下SwingWorker的源代码。
您可以使用类似于execute()方法的方法
此时,您可以创建一个Executor服务并管理池
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);
}
};
SwingWorker测试=新SwingWorker(){
私有执行器服务=新的线程池执行器(5,10,
10升,时间单位。分钟,
新建LinkedBlockingQueue(),
新螺纹工厂(){
AtomicInteger计数=新的AtomicInteger();
@凌驾
公共线程newThread(可运行的r){
返回新线程(“池SwingWorker”+count.getAndAdd(1));
}
});
@凌驾
受保护的布尔值doInBackground()引发异常{
返回true;
}
公共无效doIt(){
服务。执行(本);
}
};
您可以这样做:
- 使用现有的固定线程池启动executorservice
显示李>
- 在循环中创建您的runnable。你需要多少就有多少李>
- 您可以有50个线程和5000个可运行线程。前50次之后
runnables,无论哪个线程空闲,都将执行第51个任务,
等等
- 使用Runnable调用executorservice的execute方法
- 完成所有操作后,您将关闭executor服务
像这样:
ExecutorService executorService = Executors.newFixedThreadPool(500);
for (long i = 0; i < 1000000; i++) {
Runnable populator = new YourRunnable();
executorService.execute(populator);
}
executorService.shutdown();
while(!executorService.isTerminated()){
}
ExecutorService ExecutorService=Executors.newFixedThreadPool(500);
对于(长i=0;i<1000000;i++){
Runnable populator=newyourrunnable();
executorService.execute(填充器);
}
executorService.shutdown();
而(!executorService.isTerminated()){
}
isTerminated可用于检查executorServices是否实际关闭。由于即使在调用shutdown()方法之后也可以运行多个执行器线程(因为它们尚未完成任务),因此while循环的行为类似于等待调用
还有一件关键的事情:无论您想要传递给ExecutorService什么,它都必须是可运行的实现。在你的情况下,你的SwingWorker必须是可运行的 这很有趣。对于具有有限池的ExecutorService,您只需在需要时提交工作人员,同时只需同时执行该数量的工作人员
我制作了一个小测试应用程序,在这个程序中,你可以按按钮以你想要的速度提交一些工作人员,并且你可以看到在任何给定时间执行的工作人员数量永远不会高于你初始化ExecutorService时使用的值numberOfThreads
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class SwingWorkerExecutorTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new SwingWorkerExecutorTest();
}
});
}
public SwingWorkerExecutorTest()
{
JFrame frame = new JFrame("Frame");
int numberOfThreads = 2; //1 so they are executed one after the other.
final ExecutorService threadPool = Executors.newFixedThreadPool(numberOfThreads);
JButton button1 = new JButton("Submit SwingWorker 1");
button1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String workerName = "Worker 1";
appendMessage("Submited " + workerName);
SwingWorker worker = new TestWorker(workerName);
threadPool.submit(worker);
}
});
JButton button2 = new JButton("Submit SwingWorker 2");
button2.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String workerName = "Worker 2";
appendMessage("Submited " + workerName);
SwingWorker worker = new TestWorker(workerName);
threadPool.submit(worker);
}
});
JButton button3 = new JButton("Submit SwingWorker 3");
button3.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String workerName = "Worker 3";
appendMessage("Submited " + workerName);
SwingWorker worker = new TestWorker(workerName);
threadPool.submit(worker);
}
});
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(button1);
buttonsPanel.add(button2);
buttonsPanel.add(button3);
frame.add(buttonsPanel, BorderLayout.PAGE_END);
_textArea = new JTextArea("Submit some workers:\n");
_textArea.setEditable(false);
frame.add(new JScrollPane(_textArea));
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class TestWorker extends SwingWorker
{
public TestWorker(String name)
{
_name = name;
}
@Override
protected Object doInBackground() throws Exception
{
String message = "A " + _name + " has started!";
appendMessage(message);
doHardWork();
return null;
}
@Override
protected void done()
{
String message = "A " + _name + " has finished!";
appendMessage(message);
}
private void doHardWork()
{
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
private String _name;
}
private static void appendMessage(String message)
{
_textArea.append(message + "\n");
System.out.println(message);
}
private static JTextArea _textArea;
}
看起来是这样的:
例如,对于数量为2的线程,您将了解如果您提交了大量工作线程,那么每次需要2个线程并执行它们。当您认为:这是非常明显的强>
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);
}
ExecutorService ExecutorService=Executors.newFixedThreadPool(20);
对于(int i=0;i<500;i++){
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的布尔值doInBackground()引发异常{
System.out.println(“一个SwingWorker刚刚跑了!”);
返回true;
}
受保护的void done(){
布尔状态;
试一试{
status=get();
}捕捉(中断异常e){
//如果线程被中断,将抛出此命令。
}捕获(执行例外){
//如果我们抛出异常,就会抛出该异常
//来自doInBackground。
}
}
};
执行者服务。提交(工人);
}
它工作得很好 所以。。嗯。。如何使SwingWorker成为可运行的?我不应该这样做,但通过谷歌搜索得到的结果是:。你可以根据你的需要修改这个页面。实际上我以前访问过那个页面,但是因为糟糕的布局我关闭了它。谢谢你让我重新考虑。你不会让布局这样令人恼火的东西阻止你得到你需要的东西。:)我知道,但再加上6天的Java体验,你就明白了……正如我在上一个问题中注意到的,仔细考虑到同时运行的SwingWorker实例的数量,SwingWorker是从未来开始初始化的,不能保证每个实例都在同一时间结束或在另一个实例启动之前结束(适用于带有线程的逻辑)
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class SwingWorkerExecutorTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new SwingWorkerExecutorTest();
}
});
}
public SwingWorkerExecutorTest()
{
JFrame frame = new JFrame("Frame");
int numberOfThreads = 2; //1 so they are executed one after the other.
final ExecutorService threadPool = Executors.newFixedThreadPool(numberOfThreads);
JButton button1 = new JButton("Submit SwingWorker 1");
button1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String workerName = "Worker 1";
appendMessage("Submited " + workerName);
SwingWorker worker = new TestWorker(workerName);
threadPool.submit(worker);
}
});
JButton button2 = new JButton("Submit SwingWorker 2");
button2.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String workerName = "Worker 2";
appendMessage("Submited " + workerName);
SwingWorker worker = new TestWorker(workerName);
threadPool.submit(worker);
}
});
JButton button3 = new JButton("Submit SwingWorker 3");
button3.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String workerName = "Worker 3";
appendMessage("Submited " + workerName);
SwingWorker worker = new TestWorker(workerName);
threadPool.submit(worker);
}
});
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(button1);
buttonsPanel.add(button2);
buttonsPanel.add(button3);
frame.add(buttonsPanel, BorderLayout.PAGE_END);
_textArea = new JTextArea("Submit some workers:\n");
_textArea.setEditable(false);
frame.add(new JScrollPane(_textArea));
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class TestWorker extends SwingWorker
{
public TestWorker(String name)
{
_name = name;
}
@Override
protected Object doInBackground() throws Exception
{
String message = "A " + _name + " has started!";
appendMessage(message);
doHardWork();
return null;
}
@Override
protected void done()
{
String message = "A " + _name + " has finished!";
appendMessage(message);
}
private void doHardWork()
{
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
private String _name;
}
private static void appendMessage(String message)
{
_textArea.append(message + "\n");
System.out.println(message);
}
private static JTextArea _textArea;
}
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);
}