Java是否提供了一个ExecutorService,允许工人在同一个线程上执行?

Java是否提供了一个ExecutorService,允许工人在同一个线程上执行?,java,multithreading,concurrency,threadpool,executorservice,Java,Multithreading,Concurrency,Threadpool,Executorservice,我正在寻找ExecutorService的实现,它将提供以下语义。每个线程都由一个“工作线程”占用,该“工作线程”根据输入执行某些任务。每个辅助线程保证只在单个线程中执行,因此,应该允许它在任务之间保持状态,而不需要同步开销,因为它将在单个线程中与自身同步 假设我有100个输入,10个工作人员,我希望能够写出如下内容: for (Input input: inputs) { // The following code would pass t to all 10 workers,

我正在寻找
ExecutorService
的实现,它将提供以下语义。每个线程都由一个“工作线程”占用,该“工作线程”根据输入执行某些任务。每个辅助线程保证只在单个线程中执行,因此,应该允许它在任务之间保持状态,而不需要同步开销,因为它将在单个线程中与自身同步

假设我有100个输入,10个工作人员,我希望能够写出如下内容:

for (Input input: inputs) {
    // The following code would pass t to all 10 workers,
    // each bound to their own thread,
    // and wait for them to complete.
    executor.invokeAll(input);
}
请注意,每个工人对任何给定的输入都做不同的事情。输入不是可运行的代码块,它只是工作程序的一个参数。每个工作人员决定如何处理输入。不过,为了简化,工作人员实现了一个接口,允许以多态方式调用它,并接收输入

我用
映射
拼凑出了一些有用的东西,其中
WorkerExecutor
是我对
执行器的薄包装。newSingleThreadPool
,每个线程池中只运行一个Worker实例。我更喜欢找一些知道他们在做什么的人写的东西:-)


我同意潜在的效率低下 我意识到这种语义将导致效率低下,然而,我正试图在开发时间方面获得最大的回报,并且将Worker的每个实现重新设计为线程安全是非常重要的。我的意思是效率低下,执行可能/将看起来像这样(在本例中模拟最多2个活动线程):

问题是,在Worker 3完成之后,就没有任务要做了,在Worker 4完成之前,就不能做任何工作。这可能是任意长的CPU空闲时间



这样的执行器服务存在吗?听起来像是你真正想要的。简单地说,参与者是一个在单个线程中运行的对象,它有一个任务“邮箱”,负责按顺序处理这些任务。似乎是当前在JVM上提供参与者的主要库/框架。看那边

大致如下:

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

// you implement this for each of your non-parallelisable jobbies
interface Worker<T> {
    public void process(T input);
}

// implementation detail
class Clerk<T> {
    private final Executor executor = Executors.newSingleThreadExecutor();
    private final Worker<T> worker;

    public Clerk(Worker<T> worker) {
        this.worker = worker;
    }

    public void process(final T input) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                worker.process(input);
            }
        });
    }
}

// make one of these, and give it all your workers, then give it input
class Workshop<T> {
    private final Set<Clerk<T>> clerks = new LinkedHashSet<Clerk<T>>();

    public void addWorker(Worker<T> worker) {
        // mutable; you love it
        clerks.add(new Clerk<T>(worker));
    }

    public void process(T input) {
        for (Clerk<T> clerk : clerks) {
            clerk.process(input);
        }
    }

    public void processAll(Iterable<T> inputs) {
        for (T input : inputs) {
            process(input);
        }
    }
}
import java.util.LinkedHashSet;
导入java.util.Set;
导入java.util.concurrent.Executor;
导入java.util.concurrent.Executors;
//您为每个不可并行的工作执行此操作
接口工作者{
公共无效过程(T输入);
}
//实施细节
班主任{
private final Executor Executor=Executors.newSingleThreadExecutor();
私人最终工人;
职员(工人){
这个工人=工人;
}
公共作废流程(最终T输入){
executor.execute(新的Runnable(){
@凌驾
公开募捐{
过程(输入);
}
});
}
}
//制作其中一个,给它所有的工人,然后给它输入
班级工作坊{
私有最终集事务员=新LinkedHashSet();
公共void addWorker(Worker){
//易变的;你喜欢它
增加(新职员(工人));
}
公共作废流程(T输入){
(文员:文员){
秘书.过程(输入);
}
}
public void processAll(Iterable输入){
用于(T输入:输入){
过程(输入);
}
}
}

也许?

你试过执行器了吗?newSingleThreadExecutor()?@VishalK这不是我想要的。我确实希望事情并行运行,跨越50个线程。我描述的瘦包装器使用
newSingleThreadExecutor
向其线程提交一个worker+任务。问题是我必须编写它,毫无疑问我不知何故弄错了:)对每个线程实例状态使用
ThreadLocal
变量可以解决问题吗?@Barend这是一个有趣的建议。再说一次,这是我必须自己管理的事情,但这可能比我现在拥有的更有用。+1表示“不可并行的工作”。另外,因为它非常接近我得出的结论:
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

// you implement this for each of your non-parallelisable jobbies
interface Worker<T> {
    public void process(T input);
}

// implementation detail
class Clerk<T> {
    private final Executor executor = Executors.newSingleThreadExecutor();
    private final Worker<T> worker;

    public Clerk(Worker<T> worker) {
        this.worker = worker;
    }

    public void process(final T input) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                worker.process(input);
            }
        });
    }
}

// make one of these, and give it all your workers, then give it input
class Workshop<T> {
    private final Set<Clerk<T>> clerks = new LinkedHashSet<Clerk<T>>();

    public void addWorker(Worker<T> worker) {
        // mutable; you love it
        clerks.add(new Clerk<T>(worker));
    }

    public void process(T input) {
        for (Clerk<T> clerk : clerks) {
            clerk.process(input);
        }
    }

    public void processAll(Iterable<T> inputs) {
        for (T input : inputs) {
            process(input);
        }
    }
}