Java-每个线程有多个可运行程序
我有固定数量的线程。我希望每个线程一个接一个地运行三个Java-每个线程有多个可运行程序,java,multithreading,runnable,Java,Multithreading,Runnable,我有固定数量的线程。我希望每个线程一个接一个地运行三个Runnables。下面是一些伪代码来解释: Thread[] threads = new Thread[4]; for (int i = 0; i < threads.length; i++) { // Set the first tasks. threads[i] = new Thread(new FirstRunnable()); threads[i].start(); } for (int i = 0
Runnable
s。下面是一些伪代码来解释:
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
// Set the first tasks.
threads[i] = new Thread(new FirstRunnable());
threads[i].start();
}
for (int i = 0; i < threads.length; i++)
threads[i].join(); // wait until the first tasks are done
for (int i = 0; i < threads.length; i++) {
// Set the second task.
threads[i].setRunnable(new SecondRunnable());
threads[i].start();
}
for (int i = 0; i < threads.length; i++)
threads[i].join(); // wait until the second tasks are done
...
Thread[]threads=新线程[4];
对于(int i=0;i
使用
ThreadPool
听起来太过分了,特别是因为我正朝着性能、性能、性能的方向前进。在Java中实现这一点的最佳方法是什么?每当您看到新线程(…).start()
时,请使用该框架。特别是,无论何时看到新线程(…).start()
,都要使用框架。特别是,使用。您可以使用和“CombinedRunnable”,如下所示。该屏障允许所有线程在进入下一个可运行线程之前等待彼此完成
CyclicBarrier barrier = new CyclicBarrier(4);
Runnable r = new CombinedRunnable(barrier, new FirstRunnable(), new SecondRunnable());
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(r);
threads[i].start();
}
您可以使用和“CombinedRunnable”,如下所示。该屏障允许所有线程在进入下一个可运行线程之前等待彼此完成
CyclicBarrier barrier = new CyclicBarrier(4);
Runnable r = new CombinedRunnable(barrier, new FirstRunnable(), new SecondRunnable());
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(r);
threads[i].start();
}
Executor框架只适合您。
以下是伪代码:
1.创建执行器服务
Executors type1Runnables = Executors.newFixedThreadPool(4);
Executors type2Runnables = Executors.newFixedThreadPool(4);
等等…2.向it提交任务
for(){
type1Runnables.submit(new Runnable1());
type2Runnables.submit(new Runnable2);
}
三,。调用执行者
type1Runnables.invokeAll();
type2Runnables.invokeAll();
为了使其更通用,您可以编写自己的executorservicefactory,它接受不同的可运行类型。Executor Framework只适合您。
以下是伪代码:
1.创建执行器服务
Executors type1Runnables = Executors.newFixedThreadPool(4);
Executors type2Runnables = Executors.newFixedThreadPool(4);
等等…2.向it提交任务
for(){
type1Runnables.submit(new Runnable1());
type2Runnables.submit(new Runnable2);
}
三,。调用执行者
type1Runnables.invokeAll();
type2Runnables.invokeAll();
为了使它更通用,您可能可以编写自己的executorservicefactory,它接受不同的可运行类型。对于类中的新FixedThreadPool似乎是一个很好的用途 因此,您的代码看起来像:
ExecutorService es = Executors.newFixedThreadPool(4);
List<Future> futures = new ArrayList<Future>();
for (int x = 0; x < 4; x ++) {
futures.add(es.submit(new FirstRunnable()));
}
while (futures.size() > 0) {
futures.remove(0).get();
}
for (int x = 0; x < 4; x ++) {
futures.add(es.submit(new SecondRunnable()));
}
while (futures.size() > 0) {
futures.remove(0).get();
}
Executors服务=Executors.newFixedThreadPool(4);
列表期货=新的ArrayList();
对于(int x=0;x<4;x++){
futures.add(es.submit(newfirstrunnable());
}
while(futures.size()>0){
futures.remove(0.get();
}
对于(int x=0;x<4;x++){
futures.add(es.submit(newsecondrunnable());
}
while(futures.size()>0){
futures.remove(0.get();
}
当然,您可以很容易地重构上面的代码以消除代码重复。对于类中的新FixedThreadPool来说似乎是一个很好的用途 因此,您的代码看起来像:
ExecutorService es = Executors.newFixedThreadPool(4);
List<Future> futures = new ArrayList<Future>();
for (int x = 0; x < 4; x ++) {
futures.add(es.submit(new FirstRunnable()));
}
while (futures.size() > 0) {
futures.remove(0).get();
}
for (int x = 0; x < 4; x ++) {
futures.add(es.submit(new SecondRunnable()));
}
while (futures.size() > 0) {
futures.remove(0).get();
}
Executors服务=Executors.newFixedThreadPool(4);
列表期货=新的ArrayList();
对于(int x=0;x<4;x++){
futures.add(es.submit(newfirstrunnable());
}
while(futures.size()>0){
futures.remove(0.get();
}
对于(int x=0;x<4;x++){
futures.add(es.submit(newsecondrunnable());
}
while(futures.size()>0){
futures.remove(0.get();
}
当然,您可能很容易重构上面的代码以消除代码重复。实现这一点的惯用方法是将
执行器
与完成服务
结合使用。这允许您将许多工作单元映射到一个固定大小的线程池,并且还提供了一种优雅的机制来进行阻塞,直到所有工作完成
请注意,您对使用线程池如何影响效率的担忧实际上并不是一个问题:主要的开销是创建单个线程,而您一直都在这样做;创建池时额外的对象创建开销可以忽略不计
// Create fixed thread pool and wrap in a CompletionService to allow for easy access to completed tasks.
// We don't have an explicit result for each Runnable so parameterise the service on Void.
CompletionService<Void> cs = new ExecutorCompletionService<Void>(Executors.newFixedThreadPool(3));
// Create units of work for submission to completion service.
Runnable[] runnables = ...
// Submit runnables. Note that we don't care about the result so pass in null.
for (Runnable r : runnables) {
cs.submit(r, null);
}
// Take each *completed* result in turn, blocking until a completed result becomes available.
for (int i=0; i<runnables.length; ++i) {
Future<Void> completed = cs.take();
}
//创建固定线程池并封装在CompletionService中,以便轻松访问已完成的任务。
//对于每个Runnable,我们没有明确的结果,因此在Void上参数化服务。
CompletionService cs=新的ExecutionCompletionService(Executors.newFixedThreadPool(3));
//创建提交给完工服务的工作单元。
Runnable[]runnables=。。。
//提交runnables。注意,我们不关心结果,所以传入null。
for(Runnable r:runnables){
提交(r,空);
}
//依次获取每个*已完成*的结果,阻塞,直到有一个已完成的结果可用为止。
对于(int i=0;i实现这一点的惯用方法是使用执行器
和完成服务
。这允许您将许多工作单元映射到固定大小的线程池,还提供了一种优雅的阻塞机制,直到所有工作完成
请注意,您对使用线程池如何影响效率的担忧实际上并不是一个问题:主要的开销是创建单个线程,而您一直在这样做;创建池时额外的对象创建开销可以忽略不计
// Create fixed thread pool and wrap in a CompletionService to allow for easy access to completed tasks.
// We don't have an explicit result for each Runnable so parameterise the service on Void.
CompletionService<Void> cs = new ExecutorCompletionService<Void>(Executors.newFixedThreadPool(3));
// Create units of work for submission to completion service.
Runnable[] runnables = ...
// Submit runnables. Note that we don't care about the result so pass in null.
for (Runnable r : runnables) {
cs.submit(r, null);
}
// Take each *completed* result in turn, blocking until a completed result becomes available.
for (int i=0; i<runnables.length; ++i) {
Future<Void> completed = cs.take();
}
//创建固定线程池并封装在CompletionService中,以便轻松访问已完成的任务。
//对于每个Runnable,我们没有明确的结果,因此在Void上参数化服务。
CompletionService cs=新的ExecutionCompletionService(Executors.newFixedThreadPool(3));
//创建提交给完工服务的工作单元。
Runnable[]runnables=。。。
//提交可运行文件。请注意,我们不关心结果,所以传入null。
for(Runnable r:runnables){
提交(r,空);
}
//依次获取每个*已完成*的结果,阻塞,直到有一个已完成的结果可用为止。
对于(int i=0;它的{0..3}->4
线程和可运行性@Jon Skeet的可能重复:我不想在没有完成所有第一次运行之前启动任何第二次运行
->4
线程和可运行线程@Jon Skeet:I d的可能重复