关于 Java Collections Framework 中的非同步和同步访问?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6422887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:47:49  来源:igfitidea点击:

About unsynchronized & synchronized access in Java Collections Framework?

java

提问by unknownsatan

Can anyone explain what is unsynchronized & synchronized access in Java Collections Framework?

任何人都可以解释什么是 Java Collections Framework 中的非同步和同步访问?

采纳答案by aioobe

Synchronized vs unsynchronized access doesn't have to do with the Java Collections Framework per see.

同步与非同步访问与 Java 集合框架无关。

Synchronized access means that you have some sort of lockingfor accessing the data. This can be introduced by using the synchronizedkeyword or by using some of the higher level constructs from the java.util.concurrentpackage.

同步访问意味着您有某种锁定来访问数据。这可以通过使用synchronized关键字或使用包中的一些更高级别的构造来引入java.util.concurrent

Unsynchronized access means that you don'thave any locking involved when accessing the data.

非同步访问意味着访问数据时涉及任何锁定。

If you're using a collection in several threads, you better make sure that you're accessing it in a synchronized way, or, that the collection itself is thread safe, i.e., takes care of such locking internally.

如果您在多个线程中使用一个集合,您最好确保以同步方式访问它,或者集合本身是线程安全的,即在内部处理这种锁定。

To make sure all accesses to some collection collis accessed in a synchronized way, you can either

要确保coll以同步方式访问对某个集合的所有访问,您可以

  • ...surround accesses with synchronized (coll) { ... }

    public void someMethod() {
        synchronized (coll) {
             // do work...
        }
    }
    
  • ...encapsulate it using Collections.synchronizedCollections

    coll = Collections.synchronizedCollection(coll);
    
  • ...环绕访问 synchronized (coll) { ... }

    public void someMethod() {
        synchronized (coll) {
             // do work...
        }
    }
    
  • ...使用封装它 Collections.synchronizedCollections

    coll = Collections.synchronizedCollection(coll);
    

In the former approach, you need to make sure that every accessto the collection is covered by synchronized. In the latter approach, you need to make sure that every referencepoints at the synchronized version of the collection.

在前一种方法中,您需要确保对集合的每次访问都包含在synchronized. 在后一种方法中,您需要确保每个引用都指向集合的同步版本。

As pointed out by @Fatal however, you should understand that the latter approach only transforms a thread unsafe collection into a thread safe collection. This is most often not sufficient for making sure that the class youare writing is thread safe. For an example, see @Fatals comment.

然而,正如@Fatal 所指出的,您应该理解后一种方法只会将线程不安全的集合转换为线程安全的集合。这通常不足以确保正在编写的类是线程安全的。有关示例,请参阅 @Fatals 评论。

回答by Christian

Synchronized access means it is thread-safe. So different threads can access the collection concurrently without any problems, but it is probably a little bit slower depending on what you are doing.

同步访问意味着它是线程安全的。因此,不同的线程可以同时访问集合而不会出现任何问题,但根据您的操作,它可能会慢一点。

Unsynchronized is the opposite. Not thread-safe, but a little bit faster.

不同步则相反。不是线程安全的,但要快一点。

回答by Fabian Barney

The synchronized access in Java Collection Framework is normally done by wrapping with Collections.synchronizedCollection(...)etc. and only access through this wrapper.

Java Collection Framework 中的同步访问通常是通过用Collections.synchronizedCollection(...)etc.包装完成的,并且只能通过这个包装器进行访问。

There are some exceptions already synchronized like Hashtableand Vector.

有一些例外已经同步,例如HashtableVector

But keep in mind: Synchronization is done over the collection instance itself and has a scope for each method call. So subsequent calls maybe interrupted by another thread.

但请记住:同步是在集合实例本身上完成的,并且每个方法调用都有一个范围。所以后续的调用可能会被另一个线程中断。

Example: You first call isEmtpy()method getting result that it is not empty and after that you want to retrieve an element from that collection. But this second method call may fail, because collection may be empty now due to actions by another thread done between your calls.

示例:您首先调用isEmtpy()方法获取结果它不为空,然后您想从该集合中检索一个元素。但是这第二个方法调用可能会失败,因为由于在您的调用之间完成的另一个线程的操作,集合现在可能是空的。

So even with synchronized collections you've to care about synchronization and it maybe necessary to synchronize yourself outside the collection!

因此,即使使用同步集合,您也必须关心同步,并且可能需要在集合之外同步自己!