如何判断java线程中要同步的对象?

jia*_*afu 5 java synchronized

我想我可以使用任何对象作为块同步,例如:

synchronized(new Object()){
}
Run Code Online (Sandbox Code Playgroud)

但是我经常看到在需要hashmap是线程安全时同步一个hashmap.但我想我可以使用另一个对象来代替hashmap.那么哪个对象最佳同步?

aio*_*obe 12

synchronized (new Object()) { ... }什么都没用,因为没有其他线程可以抓住被锁定的对象.

您应该在对象"保护"资源上进行同步.显然,如果多个线程需要访问同一个资源,那么保护资源的对象需要对两个线程都可用.

也许你已经看到了这个:

class SomeClass {

    final private Object lock = new Object();

    void method() {
        ...
        synchronized (lock) {
            ...
        }
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,这与执行非常不同,synchronized (new Object())因为在上面的代码中,相同的对象用于执行该方法的所有线程.

但是我经常看到在需要hashmap是线程安全时同步一个hashmap.但我想我可以使用另一个对象而不是hashmap.那么哪个对象最好同步?

是的,如果哈希映射是要在多个线程之间共享的资源,那么通常在该对象上进行同步.

synchronized (someHashMap) {
    ... use someHashMap in a thread safe way ...
}
Run Code Online (Sandbox Code Playgroud)

是的,您也可以在某些成员字段上同步lock = new Object().实际上,使用专用锁定对象进行同步有时是首选,因为它不会干扰您要保护的对象的同步方法.


dac*_*cwe 6

每次使用新对象进行同步都不会使线程更安全.您需要每次都重用相同的同步对象.

除此之外,您可以使用另一个"同步对象"而不是您要锁定的数据结构(但您需要确保在所有地方使用相同的引用!;)).


实际上,许多人private final Object sync = new Object()在对象内使用专用的同步对象(例如),因为this当另一个线程可以将对象锁定在代码中的其他位置时,同步可能是危险的.

  • +1在与已知类而不是专用对象同步时应该小心,除非您确切知道该类的功能.如果该类内置了某种同步,则可能导致死锁与该类内部与其自身同步的代码冲突. (2认同)