从集合类获取同步集合是否同步一个类?

我试图了解synchronizedCollectionsynchronizedListsynchronizedMapsynchronizedSet其他此类方法的作用。据我了解,同步可以在块和方法上完成,而不是在类上完成,所以假设我有一个哈希图。

HashMap<Integer,String> hashMap = new HashMap<Integer,String>();
HashMap<Integer,String> syncHashMap = Collections.synchronizedMap(hashMap);

问题

  1. 那么上面的代码只是同步了整个syncHashMap类还是其中的每个方法?

  2. 如果我们可以简单地使用线程安全集合,例如 ConcurrentHashMapSynchronizedMap在多线程场景中,那么 Collections.synchronizedMap(hashMap)Collections 类中需要什么和其他类似方法

将非常感谢这方面的一些指导,在此先感谢。


冉冉说
浏览 193回答 4
4回答

临摹微笑

那么上面的代码只是同步了整个 syncHashMap 类还是其中的每个方法?不确定同步整个 syncHashMap 类及其中的每个方法是什么意思。如果你查看 method 的源代码Collections.synchronizedMap(hashMap),你会发现它使用synchronized关键字来修饰原始映射的每个方法。这意味着对于装饰后的地图对象,您一次只能调用其方法之一。但是不同的地图,你可以一次调用它们。你可以在这里找到它们的用法。ConcurrentHashMap 与同步 HashMap

茅侃侃

据我了解,它Collections.synchronizedMap不保证存储对象中的字段值将被同步,但映射中的每个条目在synchronized方法内修改时将被同步。它不保证任何其他内容。每当在另一个线程中修改同步映射时,其他线程中同一映射的其他引用将同步。这是我根据这个来源以及Java文档对它的粗浅理解。

小怪兽爱吃肉

有几个术语涉及您所询问的主题。同步化有许多接口和类可以帮助您在线程之间同步代码。一个Semaphore,一个CyclicBarrier或像BlockingQueue这样的同步集合。有关这些类的列表,请参阅java.util.concurrent包。synchronized块也是一种同步方式,但正确使用它需要更多经验。互斥量不同的语言(和库)以不同的方式实现标准互斥锁。这个想法保持不变——为了继续执行特定代码,一个互斥令牌,必须获得一个互斥体。在 Java 中,这种获取发生在进入synchronized块之前。线程安全简而言之,当一个类的所有方法可以从任意数量的线程以任意顺序同时访问时,它就是线程安全的。有几种方法可以实现线程安全。例如,字符串是线程安全的。它们不是同步的,但它们是不可变的,这也会导致线程安全。所有Collections.synchronized*()方法都返回集合的线程安全包装器,前提是所有未来*(*请参阅先发生关系)对它们的访问都是通过这些包装器执行的(这就是为什么初学者只调用Collections.synchronized*()onnew对象是一个很好的规则。答案根据前面段落的知识,回答你的问题:不,它不同步一个类。它根本不会改变原来的Collection实现。但是,它确实为该类创建了一个读写线程安全的同步可变代理。

哔哔one

在回答您的问题之前,让我们重申一些同步的基础知识同步总是在一个对象/实例上。每个同步实例都由一个锁(称为互斥锁)保护。任何在对象上调用同步方法的线程都必须先获取该锁,然后再调用该方法。调用未同步方法的原因不需要此锁获取。回答你的问题:那么上面的代码只是同步了整个 syncHashMap 类还是其中的每个方法?是的,它确实。在这里查看Collections.SynchronizedMap 的源代码即可。注意几乎每个方法都有同步(互斥)块。如果我们可以在多线程场景中简单地使用线程安全的集合,例如 ConcurrentHashMap 或 SynchronizedMap,那么 Collections 类中的 Collections.synchronizedMap(hashMap) 和其他类似方法的需求是什么?好吧,同步每个方法(包括只读类型的方法)都有缺点。它不必要地减慢了读取操作,因此您的观察是正确的,即使用诸如 ConcurrentHashMap 之类的实现,它只锁定正在修改集合的方法。只读方法不同步,因此在具有并发读/写操作的多线程场景中速度更快。Collections.synchronizedMap 提供的唯一优势是保留输入键的顺序。因此,当您需要时,您可以使用 Collections.synchronizedMap。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java