對(duì)Java同步一些理解
對(duì)Java同步一些理解
kingfish 2005
------------------------------------------------------------
基本概念:
每個(gè)Object都會(huì)有1個(gè)鎖.
同步就是串行使用一些資源.
(說明:以下有些例子為了突出重點(diǎn),省略了不必要的代碼.特別是省掉了一些成員變量,就是需要同步的對(duì)象.)
1. 多線程中對(duì)共享、可變的數(shù)據(jù)進(jìn)行同步.
對(duì)于函數(shù)中的局部變量沒必要進(jìn)行同步.
對(duì)于不可變數(shù)據(jù),也沒必要進(jìn)行同步.
多線程中訪問共享可變數(shù)據(jù)才有必要.
2. 單個(gè)線程中可以使用synchronized,而且可以嵌套,但無意義.
class Test {
public static void main(String[] args) {
Test t = new Test();
synchronized(t) {
synchronized(t) {
System.out.println("ok!");
}
}
}
}
3. 對(duì)象實(shí)例的鎖
class Test{
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(this){
//do something here
}
}
}
上面的f1()和f2()效果一致, synchronized取得的鎖都是Test某個(gè)實(shí)列(this)的鎖.
比如: Test t = new Test();
線程A調(diào)用t.f2()時(shí), 線程B無法進(jìn)入t.f1(),直到t.f2()結(jié)束.
作用: 多線程中訪問Test的同一個(gè)實(shí)例的同步方法時(shí)會(huì)進(jìn)行同步.
4. class的鎖
class Test{
final static Object o= new Object();
public static synchronized void f1(){
//do something here
}
public static void f2(){
synchronized(Test.class){
//do something here
}
}
public static void f3(){
try {
synchronized (Class.forName("Test")) {
//do something here
}
}
catch (ClassNotFoundException ex) {
}
}
public static void g(){
synchronized(o){
//do something here
}
}
}
上面f1(),f2(),f3(),g()效果一致
f1(),f2(),f3()中synchronized取得的鎖都是Test.class的鎖.
g()是自己產(chǎn)生一個(gè)對(duì)象o,利用o的鎖做同步
作用: 多線程中訪問此類或此類任一個(gè)實(shí)例的同步方法時(shí)都會(huì)同步. singleton模式lazily initializing屬于此類.
5. static method
class Test{
private static int v = 0;
public static void f1(){
//do something, 但函數(shù)中沒用用到v
}
public synchronized static void f2(){
//do something, 函數(shù)中對(duì)v進(jìn)行了讀/寫.
}
}
多線程中使用Test的某個(gè)實(shí)列時(shí),
(1) f1()是線程安全的,不需要同步
(2) f2()這個(gè)靜態(tài)方法中使用了函數(shù)外靜態(tài)變量,所以需要同步.
6. 對(duì)線程的run()進(jìn)行同步?jīng)]有意義,如 public synchronized void run()
class Test extends Thread{
public synchronized void run(){
while(true){
//do something
}
}
public synchronized void f(){
//...
}
}
這種例子會(huì)有一個(gè)問題, 執(zhí)行run()時(shí)(內(nèi)部在循環(huán)), 外部無法執(zhí)行f()
class Test extends Thread{
public synchronized void run(){
//do something
}
}
這種例子同步基本沒用, 因?yàn)閞un()通常靠 new Test().start()來執(zhí)行的.
因?yàn)門est實(shí)例不同,鎖也不同.
posted on 2005-02-27 17:37 辰 閱讀(237) 評(píng)論(0) 編輯 收藏 所屬分類: J2se