Collections.synchronizedList()方法有什么用?它似乎没有同步列表 [英] What is the use of Collections.synchronizedList() method? It doesn't seem to synchronize the list

查看:457
本文介绍了Collections.synchronizedList()方法有什么用?它似乎没有同步列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用两个线程将 String 值添加到 ArrayList 。我想要的是,当一个线程添加值时,另一个线程不应该干扰,所以我使用了 Collections.synchronizedList 方法。但似乎如果我没有在对象上显式同步,则以不同步的方式完成添加。

I am trying to add String values to an ArrayList using two threads. What I want is that while one thread is adding the values the other thread should not interfere so I have used the Collections.synchronizedList method. But it appears that if I don't explicitly synchronize on an object the adding is done in an unsynchronized way.

没有显式同步块:

public class SynTest {
    public static void main(String []args){
        final List<String> list=new ArrayList<String>();
        final List<String> synList=Collections.synchronizedList(list);
        final Object o=new Object();
        Thread tOne=new Thread(new Runnable(){

            @Override
            public void run() {
                //synchronized(o){
                for(int i=0;i<100;i++){
                    System.out.println(synList.add("add one"+i)+ " one");
                }
                //}
            }

        });

        Thread tTwo=new Thread(new Runnable(){

            @Override
            public void run() {
                //synchronized(o){
                for(int i=0;i<100;i++){
                    System.out.println(synList.add("add two"+i)+" two");
                }
                //}
            }

        });
        tOne.start();
        tTwo.start();
    }
}

我得到的输出是:

true one
true two
true one
true two
true one
true two
true two
true one
true one
true one...

显式同步块取消注释我在添加时停止来自其他线程的干扰。一旦线程获得了锁,它就会执行直到它完成。

With the explicit synchronized block uncommented I'm stopping the interference from the other thread while adding. Once the thread has acquired the lock it is executing until it is finished.

取消注释同步块后的示例输出:

sample output after uncommenting the synchronized block:

true one
true one
true one
true one
true one
true one
true one
true one...

那么为什么 Collections.synchronizedList()没有进行同步?

So why is the Collections.synchronizedList() not doing the synchronization?

推荐答案

同步列表仅同步此列表的方法。

A synchronized list only synchronizes methods of this list.

这意味着当另一个线程当前正在运行此列表中的方法时,线程将无法修改列表。处理方法时对象被锁定。

It means a thread won't be able to modify the list while another thread is currently running a method from this list. The object is locked while processing method.

例如,假设两个线程在列表中运行 addAll ,有2个不同的列表( A = A1,A2,A3 B = B1,B2,B3 )作为参数。

As an example, Let's say two threads run addAllon your list, with 2 different lists (A=A1,A2,A3, B=B1,B2,B3) as parameter.


  • 由于方法已同步,您可以确定这些列表不会像一样随机合并A1,B1,A2,A3,B2,B3

您没有决定某个线程何时将该流程移交给另一个线程,所以你可以得到 A1,A2,A3,B1,B2,B3 B1,B2,B3,A1,A2,A3

You don't decide when a thread handover the process to the other thread so you can either get A1,A2,A3,B1,B2,B3 or B1,B2,B3,A1,A2,A3.

在第一段代码中,两个线程同时运行。并且都尝试将添加元素添加到列表中。除了 add 方法上的同步之外,你没有办法阻止一个线程,所以没有什么能阻止线程1运行多个 add 在将流程移交给线程2之前的操作。所以你的输出是完全正常的。

In your first piece of code, both threads runs on the same time. And both try to add an element to the list. You don't have any way to block one thread except the synchronization on the add method so nothing prevent thread 1 from running multiple add operation before handing over the process to thread 2. So your output is perfectly normal.

在你的第二段代码(未注释的代码)中,你明确指出一个线程在开始循环之前从另一个线程完全锁定列表。因此,您可以确保您的某个线程在另一个线程可以访问列表之前运行完整循环。

In your second piece of code (the uncommented one), you clearly state that a thread completely lock the list from the other thread before starting the loop. Hence, you make sure one of your thread will run the full loop before the other one could access the list.

这篇关于Collections.synchronizedList()方法有什么用?它似乎没有同步列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆