2012-01-08 43 views
2

當使用這樣的事情:使用同步(鎖定)時,鎖定對象最好是靜態的還是非靜態的?

private final Object lock = new Object() 

有靜態和非靜態的有什麼區別?

可以將非靜態對象鎖定靜態方法,反之亦然?

+1

這完全取決於你所抵禦的東西。您需要了解鎖對象的用途。 – SLaks 2012-01-08 00:52:04

+1

'static'意味着在同一個類的所有實例中只會創建一個該對象的副本。 – 2012-01-08 00:52:38

回答

1

它一如既往地依賴於情況。你想要做什麼?如果全局共享一個鎖,它應該是靜態的。如果你想要同步的是非靜態的,那麼你可能不應該使用靜態鎖定對象,因爲這會阻止同時訪問單獨的實體。

1

最大的區別是,鎖定非靜態對象意味着您可能鎖定兩個不同的對象,因此不提供任何互斥。如果需要僅在對象級別提供互斥,那麼也許這就是你想要的。 (事實上​​,當你同步一個(非靜態)方法時發生了什麼:你正在同步this,這絕對不是一個靜態對象。)

3

如果你使用的是非靜態鎖,該對象的每個實例都將有一個不同的鎖定對象,這將是調用的一個潛在的更細粒度相當於:

synchronized(this) { 

} 

這就是說:你只鎖定對其他訪問是從同一個對象中。使用靜態鎖定,類的每個實例共享鎖定對象。所以在任何給定的時間只有一個線程可以訪問同步塊。

所以這取決於你在做什麼。在前一種情況下,除非您有多個這些鎖保護較小的數據子集,否則打擾分配一個鎖對象是沒有意義的。在後一種情況下,你基本上(再次,更細粒度的)這樣做:

synchronized(MyObject.class) { 

} 

也就是說,你對鎖定所有的訪問,無論你是否有相同的對象或不同的做訪問。

這取決於你想要完成什麼,以及你鎖定什麼,以及如何使用這些鎖。如果您保護的是每個實例的狀態,那麼您可能需要每個實例(非靜態)鎖定對象。如果你正在保護全局狀態,你需要一個在每個人中共享的靜態鎖定對象。