static靜態塊使用多執行緒的問題

2021-10-21 03:23:58 字數 1136 閱讀 8694

public

class

mytest

catch

(interruptedexception e)

b.test()

;//---1---

}public

static

void

test()

}static

class

bpublic

static

void

test()

}public

static

void

main

(string[

] args)

throws interruptedexception

}

在上面的**中線程1執行類a的靜態方法,會先拿到類a的**初始化鎖**,初始化類a,執行類a的靜態**塊,執行到"---1---"之前先休息一秒.

在這一秒內線程2執行類b的靜態方法,會先拿到類b的**初始化鎖**,初始化類b,執行類b的靜態**塊,執行到"---2---"時,想呼叫類a的靜態方法,結果類a未初始化完成,執行緒2就開始等待阻塞.

執行緒1在1秒後開始執行"---1---"呼叫類b的靜態方法,結果類b也沒有初始化完成,類a開始等待阻塞.

在這時,兩個執行緒相互等待就造成了死鎖.

static

catch

(interruptedexception e)}}

public

static

void

main

(string[

] args)

在jdk8中可以使用lamda表示式,lamda表示式的原理是生成了乙個靜態內部類和乙個

靜態方法,這個靜態內部類實現了函式式程式設計的介面,在實現的函式式方法中呼叫

了該靜態方法.只要呼叫了靜態方法就會和情況1一樣產生死鎖.

在這種執行緒鎖下,用工具檢視執行緒的狀態是running,但是,實際是阻塞,這個應該是jvm

的bug,可以檢視thread的dump,可以看到呼叫object.wait()方法.

static靜態初始化塊

j a 中可以通過初始化塊進行資料賦值。如 在類的宣告中,可以包含多個初始化塊,當建立類的例項時,就會依次執行這些 塊。如果使用 static 修飾初始化塊,就稱為靜態初始化塊。需要特別注意 靜態初始化塊只在類載入時執行,且只會執行一次,同時靜態初始化塊只能給靜態變數賦值,不能初始化普通的成員變數。...

多執行緒中使用靜態方法

類的成員分為兩類,靜態成員 static member 和例項成員 instance member 靜態成員屬於類,例項成員則屬於物件,即類的例項。簡單討論一下在乙個類中使用靜態字段 static field 和靜態方法 static method 是否會有執行緒安全問題。我們在知道,靜態字段 st...

多執行緒中static物件

include class staticinit static staticinit getinstance void testfun static staticinit instance int main 如上面 對於單個執行緒來說,是安全的。但是對於多執行緒就不好說了,主要是涉及到static物...