我想我可以用任何物体来进行同步的块如:如何判断在java线程中要同步哪个对象?
synchronized(new Object()){
}
,但我经常看到一个同步的HashMap时需要的HashMap是线程safe.but我想我可以用一个其它的对象,而不是的散列图。那么哪个对象最好同步呢?
我想我可以用任何物体来进行同步的块如:如何判断在java线程中要同步哪个对象?
synchronized(new Object()){
}
,但我经常看到一个同步的HashMap时需要的HashMap是线程safe.but我想我可以用一个其它的对象,而不是的散列图。那么哪个对象最好同步呢?
做synchronized (new Object()) { ... }
是没有用的根本,因为没有其他线程将永远得到它反正锁定的对象保持。
你应该对象“守卫”的资源上进行同步。很显然,如果有多个线程需要访问相同的资源,则守护资源的对象需要可用于两个线程。
也许你已经看到了这一点:
class SomeClass {
final private Object lock = new Object();
void method() {
...
synchronized (lock) {
...
}
...
}
}
当然,这是从,因为在上面的代码做synchronized (new Object())
很大的不同,同一个对象被用于执行方法的所有线程。
但我常常看到一个同步的HashMap时需要的HashMap是线程safe.but我想我可以用一个其它的对象,而不是HashMap中。那么哪个对象最好同步?
吧,如果哈希映射为多个线程之间共享资源,那么它是常见对该对象进行同步。
synchronized (someHashMap) {
... use someHashMap in a thread safe way ...
}
是的,你也可以同步一些成员字段lock = new Object()
以及。事实上,使用专用锁对象进行同步有时是首选,因为它不会影响您保护的对象的同步方法。
每次使用新对象进行同步不会使线程更安全。您需要每次重用相同的同步对象。
其他然后,你可以使用另一种“同步对象”比你锁定的数据结构(但你需要确保你使用相同的参考无处不在;!))。
事实上,许多使用专用同步对象(例如private final Object sync = new Object()
)的对象中,因为同步this
可能是危险的,当另一个线程可以在代码的其他地方锁定的对象。
它真的不重要,只要你每次都使用同一个。我个人比较喜欢使用需要同步(如您的HashMap
),因为它传达更清楚,我是同步的实际的对象,并且不需要另一个对象实例(可能凌乱变量)。
请注意,如果你实际使用:
synchronized(new Object()) {
// ...
}
,那么你就错了,因为new Object()
创建一个新的对象,每次;您需要保持相同的参考才能正确同步。
非常感谢你! – jiafu 2012-03-23 14:53:23
首先,做synchronized(new Object())
是一个坏主意,因为每个线程都会创建自己的对象,所以同步就没有意义。
在希望同步访问现有对象的示例中,对该对象进行同步是有意义的。创建一些其他对象进行同步没有任何好处。然而,如果你想做更多的事情来提高并发性 - 比如说把地图可能的键分成几组,然后用不同的锁保护每一组 - 然后创建单独的组合要同步的对象可能很有用。但是,除非您真的确定了需要解决的性能问题,否则我不会为此类问题而烦恼。
-1代表“创建一些其他对象进行同步没有任何好处。”如果你同步到一个在它自己的方法中同步自己的现有对象,那么你可能会导致死锁而没有意识到它。 – 2012-03-23 14:56:57
@ErickRobertson - 哈?死锁要求在两个不同的对象上获取锁。如果一个线程获得对象A的锁定,然后调用该对象中的同步方法,它已经保存了锁定,所以没有问题。 – 2012-03-23 15:03:51
在多线程系统中,其他线程也可能与该对象交互。有几种方法可能是另一个线程可能已经锁定了对象,并尝试获取第一个线程在尝试同步到该对象时已拥有的锁定。 – 2012-03-23 16:23:46
似乎没有人提及它,但根据您的要求,首先使用线程安全对象可能使您可以删除所有锁定逻辑。
在HashMap
的情况下,有ConcurrentHashMap
,它是一个线程安全版本,具有一些额外的原子操作(putIfAbsent等)。
非常感谢你! – jiafu 2012-03-23 14:37:21
不客气:-) – aioobe 2012-03-23 14:39:13