[英]Java synchronized and static synchronized method accessing static field
在靜態同步方法和實例同步方法試圖訪問不同線程中相同類的靜態字段的以下程序的行為是什么? 任何線程都會被阻塞嗎? 它非常混亂。
class MyClass
{
public static int i = 5;
public synchronized void m1()
{
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
public static synchronized void m3()
{
//T2 will be able to call this method on same object lock while it is using
//static field i???
System.out.println(i);//uses static field i of MyClass
}
}
同步實例方法等效於
public void m1() {
synchronized(this) {
...
}
}
(嗯,它們並不完全相同,但是您的問題的答案不會受到這種差異的影響)。
同步的靜態方法在類上同步:
public void m2() {
synchronized(MyClass.class) {
...
}
}
如您所見,兩個塊在差異對象上同步: m1
在調用它的實例上同步,而m2
在Class<MyClass>
實例上同步,該實例表示您在JVM中的類。 因此可以調用這兩種方法而不會互相阻塞。
您始終在對象上進行同步。
Funciton m1在調用它的對象的實例上同步。
函數m3在類本身上同步。
m1可以寫成:
public void m1()
{
synchronized(this) {
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
}
因此,您正在兩個不同的對象上進行同步,並且這兩種方法可以同時訪問任何全局變量。
方法m1和m3可以獨立執行。
因為正如您已經說過的, static synchronized
在對象上。 因此與synchronize(MyClass.class)
相同。
synchronized
的實例可用。 因此,僅在實例中阻止它。 它將與使用相同:
MyClass myClass = new MyClass();
synchronize (myClass)
{
.....
}
您的示例代碼看起來不錯。
確保根據我的靜態變量同步的最佳方法是。 由於鎖對象在您的類之外無法訪問。 見下文。
public class MyClass
{
private static int i = 0;
private static final Object lockObject = new Object();
public void m1() {
synchronized (lockObject ) {
//Use you static var
}
}
public void m3() {
synchronized (lockObject ) {
//Use you static var
}
}
}
Java沒有任何與訪問靜態字段有關的同步控件。
如果您將方法設為空,則同步將完全相同。
具體來說,只要任何線程正在執行該類型的任何同步靜態方法,所有其他調用同步靜態方法的線程都將等待它們完成,以便最多可以立即執行一個同步靜態方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.