【问题标题】:Non deterministic behavior with synchronizedListsynchronizedList 的非确定性行为
【发布时间】:2014-11-03 11:32:54
【问题描述】:

我正在尝试理解Collections.synchronizedList() 的概念,但是下面的代码无法正常工作。据我了解,synchronizedList 将同步 ArrayList 的所有方法并将其放入 synchronised 块中将阻止其他线程访问/修改获取锁的对象。下面是我的代码。

 public class SynchronisedList {

    /**
     * @param args
     */

    static ArrayList<String> list=new ArrayList<String>();


    public static void main(String[] args) {
        // TODO Auto-generated method stub

        for(int i=0;i<50000;i++)
            list.add("String"+i);


        final List<String> list1=Collections.synchronizedList(list); 

        Thread thread=new Thread(new Runnable() {

            @Override
            public void run() {

                System.out.println("Thread 1 started");

                synchronized (list1) 
                {
                    for(int i=0;i<50000;i++)
                    {

                        System.out.println(list1.get(i));
                        //System.out.println(list.get(i));
                    }
                }
            }
        });

        Thread thread1=new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("Thread 2 started");
                list1.clear();
        }
        });


        thread.start();

        thread1.start();

    }

}

我的预期输出是线程 1 将通过 arraylist list1 进行迭代,然后线程 2 将清除它。但我收到错误,

Exception in thread "Thread-0" java.lang.IndexOutOfBoundsException: Index: 432, Size: 0
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at java.util.Collections$SynchronizedList.get(Collections.java:1816)
    at com.common.List.SynchronisedList$1.run(SynchronisedList.java:35)
    at java.lang.Thread.run(Thread.java:619)

我在这里做错了吗?请帮忙。

【问题讨论】:

  • Thread2 在未同步的list 上工作,得到的结果是意料之中的!创建同步的list1(由list 支持)不会自动使list 安全。
  • @ammoQ 我已将list 替换为list1,但仍然出现同样的错误。
  • thread.start(); thread1.start(); 并不意味着thread1 不能比thread 更快地锁定thread,只是偶然。

标签: java multithreading arraylist


【解决方案1】:

要实现你的预期输出,迭代和清除都应该在synchronized块中,并且你应该在原始列表上同步,list1是多余的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多