我正在用Java编写一个负载测试应用程序,并且有一个线程池可以对正在测试的服务器执行任务。所以要创建1000个作业并在5个线程中运行它我会做这样的事情:
ExecutorService pool = Executors.newFixedThreadPool(5);
List<Runnable> jobs = makeJobs(1000);
for(Runnable job : jobs){
pool.execute(job);
}
但是我不认为这种方法可以很好地扩展,因为我必须提前制作所有“工作”对象并让它们在内存中存放直到需要它们为止。
我正在寻找一种方法让池中的线程在每次需要新工作时进入某种“JobFactory”类,并且工厂根据请求构建Runnables,直到所需的工作数量为止已经运行了。工厂可能会开始返回'null',向线程发出信号,表示没有更多的工作要做。
我可以手动编写这样的代码,但它似乎是一个常见的用例,并且想知道在我可以使用的奇妙但复杂的“java.util.concurrent”包中是否有任何东西?< / p>
答案 0 :(得分:5)
您可以使用AtomicInteger在线程池的执行线程中完成所有工作,以监控已执行的可运行数量
int numberOfParties = 5;
AtomicInteger numberOfJobsToExecute = new AtomicInteger(1000);
ExecutorService pool = Executors.newFixedThreadPool(numberOfParties );
for(int i =0; i < numberOfParties; i++){
pool.submit(new Runnable(){
public void run(){
while(numberOfJobsToExecute.decrementAndGet() >= 0){
makeJobs(1).get(0).run();
}
}
});
}
您还可以将返回的Future存储在List中,并将get()
存储在它们上以等待完成(以及其他机制)
答案 1 :(得分:4)
槽糕。您可以创建具有固定容量的BlockingQueue<Runnable>
,并让每个工作线程将Runnable
出列并运行它。然后你可以有一个生产者线程,这就是将作业放入队列的原因。
主线程会做类似的事情:
// 100 is the capacity of the queue before blocking
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(100);
// start the submitter thread
new Thread(new JobSubmitterThread(queue)).start();
// make in a loop or something?
new Thread(new WorkerThread(queue)).start();
new Thread(new WorkerThread(queue)).start();
...
工人看起来像是:
public class WorkerThread implements Runnable {
private final BlockingQueue<Runnable> queue;
public WorkerThread(BlockingQueue<Runnable> queue) {
this.queue = queue;
}
public void run() {
// run until the main thread shuts it down using volatile boolean or ...
while (!shutdown) {
Runnable job = queue.take();
job.run();
}
}
}
作业提交者看起来像是:
public class JobSubmitterThread implements Runnable {
private final BlockingQueue<Runnable> queue;
public WorkerThread(BlockingQueue<Runnable> queue) {
this.queue = queue;
}
public void run() {
for (int jobC = 0; jobC < 1000; jobC++) {
Runnable job = makeJob();
// this would block when the queue reaches capacity
queue.put(job);
}
}
}