由多个线程访问synchronizedList

时间:2013-08-26 06:48:35

标签: java multithreading

我对SynchronizedList有一个非常基本的问题。

假设我将synchronizedList作为 -

List syncList = Collections.synchronizedList(new ArrayList<>())

现在我的场景是线程A正在尝试访问add() api和线程B试图访问synchronizedList的remove() api。两个线程是否能够同时访问Both(添加和删除)api。

我相信线程不应该同时访问api(add()和remove())。如果我错了,请纠正我。

4 个答案:

答案 0 :(得分:6)

  

Both线程是否能够访问Both(添加和删除)api   同时。

答案是否定的。

如果您有机会查看Collections.synchronizedList(List)源代码,您会看到,该方法正在创建名为静态内部类的实例 SynchronizedListSynchronizedRandomAccessList,具体取决于您作为参数发送的List的类型。

现在这两个静态内部类都扩展了一个名为SynchronizedCollection的公共类,该类维护一个mutex对象,所有方法操作都在该对象上进行同步

mutex对象已分配this,这实际上意味着mutex对象是相同的返回实例

由于add()remove()方法是在

下执行的
synchronized(mutex) {

}

阻止,执行add线程(并在mutex上获取锁定),将不允许另一个线程执行{{1 (通过在同一个remove上获取锁定),因为前者已经锁定 mutex后一个帖子等待,直到mutex前线程获得的锁定获得释放

所以,是mutexadd() 互斥

答案 1 :(得分:1)

你能否“同时”澄清你的意思?

同步数据结构将强制两个线程中的一个等待,直到另一个线程完成其操作。 “等待锁定”可以在不同的粒度级别强制执行,并且可以在同步写入(包括删除)时允许读取,但原则保持不变。

答案 2 :(得分:0)

我会用这种方式解决你的问题:

首先我创建一个这样的列表包装类:

public class MySyncList{
   private List<String> myList;
   public MySyncList(){
      this.myList = new ArrayList<String>();
   }
   public synchronized void add(String elem){
      this.myList.add(elem);
   }
   public synchronized void remove(String elem){
      this.myList.remove(remove);
   }
   public synchronized List<String> getList(){
      return this.myList;
   }
}

比从线程访问:

final MySyncList list = new MySyncList(); // final so other threads can access it

ExecutorService service = Executors.newFixedThreadPool(10);
for(int i=0;i<20;i++){
   service.execute(new Runnable(){
      public void run(){
         list.add("something");
         list.remove("something");
      }
   });
}
service.shutDown();
while(!service.isTerminated());
List<String> finalList = list.getList();

答案 3 :(得分:-1)

这是正确的,同步列表是完全线程安全的。因此,就原子性而言,线程将无法同时访问列表。不同线程的访问将以串行方式进行。