繁体   English   中英

两个线程之间的同步Arraylist不会返回相同的值

[英]Synchronized Arraylist between two threads doesn't return the same value

我有以下代码:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class MyThread implements Runnable{

    private List<Integer> myList;

    public MyThread(List<Integer> list){
            this.myList = list;
    }
    private void updateList(int i){
           synchronized (myList) {
               myList.add(i);
           }
    }
    @Override
    public void run() {
        for( int i = 0; i < 1000000;i++){
                updateList(i);
        }
        System.out.println("end: " + myList.size());
    }
}
public class MyExecutor {

    private List<Integer> taskList = new ArrayList<>();
    private void launch(){

        ExecutorService executorService= Executors.newFixedThreadPool(10000);
        executorService.execute(new MyThread(taskList));
        executorService.execute(new MyThread(taskList));
        executorService.shutdown();
    }
    public static void main(String[] args) {
        MyExecutor test = new MyExecutor();
        test.launch();
    }
}

输出应为: 2000000

我将得到不同的结果,这意味着这两个线程正在替换彼此的值。

我不知道问题出在哪里,对此代码进行了几次修改,但都没有解决问题。 (用Vector替换/在构造函数中添加了同步/在volatile中添加了)

为什么此代码无法正常工作?

编辑

在两个线程我预计将获得1000000

输出应为:2000000

否,原因如下:

  1. 您要打印两件事,因此输出不会是一个数字。
  2. 当每个线程恰好添加了1000000个东西时,它将打印大小; 您不知道其他线程在这一点上做了多少。
  3. 您没有以同步的方式访问大小,因此您有可能获取不最新的值。

你越来越

end: 1065878
end: 2000000

第一行来自首先完成其工作的线程。 它不应完全是1M ,因为有多个线程正在工作。 可以合理地假设,当第一个线程完成添加其1M ,另一个线程至少添加了一个。

由于采用了同步方法,第二行始终为2M (如您所预期)。

我猜第一个线程应该针对我想要的确切数目执行,不多也不少。

事情并行发生。 线程正在运行。 每个人都试图调用updateList :一个进入,其他人等待。 没有人优先考虑下一个人,因此该方法的控制权以相当随机的方式在所有工人之间传递。

我敢打赌,您仍在考虑顺序执行:)一个线程运行整个run方法,打印1M ,另一个线程处理一个1M大小的列表并添加其部分。

为了更好地理解它,请添加打印声明

private void updateList(int i) {
    synchronized (myList) {
        myList.add(i);
        System.out.println(Thread.currentThread().getName() + " added " + i);
    }
}

并减少任务要添加的元素数量,例如10

pool-1-thread-1 added 0
pool-1-thread-1 added 1
pool-1-thread-1 added 2
pool-1-thread-1 added 3
pool-1-thread-2 added 0
pool-1-thread-2 added 1
pool-1-thread-2 added 2
pool-1-thread-2 added 3
pool-1-thread-1 added 4
pool-1-thread-1 added 5
pool-1-thread-1 added 6
pool-1-thread-1 added 7
pool-1-thread-1 added 8
pool-1-thread-1 added 9
end: 14
pool-1-thread-2 added 4
pool-1-thread-2 added 5
pool-1-thread-2 added 6
pool-1-thread-2 added 7
pool-1-thread-2 added 8
pool-1-thread-2 added 9
end: 20

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM