Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-每个线程有多个可运行程序_Java_Multithreading_Runnable - Fatal编程技术网

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的可能重复