Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.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_Parallel Processing - Fatal编程技术网

在Java中并行迭代单个列表而不重复

在Java中并行迭代单个列表而不重复,java,multithreading,parallel-processing,Java,Multithreading,Parallel Processing,我有一个填充了“someObject”的ArrayList。我需要用4个不同的线程(使用Futures和Callables)遍历这个列表。线程将保留它遇到的前5个值对象。我第一次尝试创建一个并行流,但效果不太好。是否有一些明显的事情我没有想到,因此每个线程可以迭代对象,而不可能捕获同一对象两次?您可以使用 class MyRunnable implements Runnable { final List<SomeObject> list; final AtomicIn

我有一个填充了“someObject”的ArrayList。我需要用4个不同的线程(使用Futures和Callables)遍历这个列表。线程将保留它遇到的前5个值对象。我第一次尝试创建一个并行流,但效果不太好。是否有一些明显的事情我没有想到,因此每个线程可以迭代对象,而不可能捕获同一对象两次?

您可以使用

class MyRunnable implements Runnable {
    final List<SomeObject> list;
    final AtomicInteger counter; // initialize to 0

    public void run() {
        while(true) {
            int index = counter.getAndIncrement();
            if(index < list.size()) {
                do something with list.get(index);
            } else {
                return;
            }
        }
    }
}
类MyRunnable实现Runnable{
最后名单;
最终AtomicInteger计数器;//初始化为0
公开募捐{
while(true){
int index=counter.getAndIncrement();
如果(索引

只要每个
MyRunnable
具有相同的
AtomicInteger
引用,它们就不会重复索引

您不需要
AtomicInteger
或任何其他同步

您应该简单地根据处理线程的数量(其数量也是预先知道的)对列表(其大小是预先知道的)进行逻辑分区,并让每个线程在列表的[from,to]中自己的部分上操作

这就完全避免了对任何同步的需要(即使它只是一个优化的同步,比如
AtomicInteger
),这是您应该一直努力实现的(只要它是安全的)

伪码

class Worker<T> implements Runnable {
    final List<T> toProcess;

    protected Worker(List<T> list, int fromInc, int toExcl){
       // note this does not allow passing an empty list or specifying an empty work section but you can relax that if you wish
       // this also implicitly checks the list for null
       Preconditions.checkArgument(fromInc >= 0 && fromInc < list.size());
       Preconditions.checkArgument(toExcl > 0 && fromInc <= list.size());
       // note: this does not create a copy, but only a view so it's very cheap
       toProcess = list.subList(fromInc, toExcl);
    }

    @Override
    public final void run() {
       for(final T t : toProcess) {
           process(t);
       }
    }

    protected abstract process(T t);
}
类工作程序实现可运行{
最终处理列表;
受保护的工作程序(列表、int-fromInc、int-toExcl){
//注意,这不允许传递空列表或指定空工作部分,但如果您愿意,您可以放松
//这还隐式检查列表是否为null
预条件.checkArgument(fromInc>=0&&fromInc先决条件。checkArgument(toExcl>0&&fromInc)我不确定我是否在跟踪这个问题,但可能会将对象分成四个子列表,每个线程一个子列表?