4

我对SynchronizedList.

可以说我有 synchronizedList 作为 -

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

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

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

4

4 回答 4

6

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

答案是不。

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

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

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

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

synchronized(mutex) {

}

块,一个执行(并获取锁)的线程,将不允许另一个线程执行(通过获取相同的锁),因为前者已经锁定了. 后一个线程将一直等待,直到前一个线程获得的释放addmutexremovemutexmutexmutex

所以,是的add(),并且remove()互斥的

于 2013-08-26T07:02:19.403 回答
1

你能澄清一下“同时”是什么意思吗?

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

于 2013-08-26T06:52:34.627 回答
-1

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

首先,我创建一个列表包装类,如下所示:

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();
于 2013-08-26T06:57:01.340 回答
-1

没错,同步列表是完全线程安全的。因此,就原子性而言,线程将无法同时访问列表。来自不同线程的访问将以串行方式发生。

于 2013-08-26T07:04:14.020 回答