java synchronized詳解

Java語言的關鍵字,當它用來修飾一個方法或者一個代碼塊的時候,可以保證在同一時刻最多隻有一個線程執行該段代碼。 1、當兩個併發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程獲得執行。另外一個線程必須等待當前線程執行完這個代碼塊之後才能執行該代碼塊。 2、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另外一個線程仍然能夠訪問該object中的非synchronized(this)同步代碼塊。 3、尤爲關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其餘線程對object中全部其它synchronized(this)同步代碼塊的訪問將被阻塞。 4、第三個例子一樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就得到了這個object的對象鎖。結果,其它線程對該object對象全部同步代碼部分的訪問都被暫時阻塞。 5、以上規則對其它對象鎖一樣適用.併發

例1:當兩個併發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程獲得執行。另外一個線程必須等待當前線程執行完這個代碼塊之後才能執行該代碼塊。 public class Test implements Runnable{ public void run() {
// synchronized(this) { //線程阻塞 for (int i = 0; i < 5000; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
}
// }
public static void main(String[] args) {
Test t1 = new Test();
Thread ta = new Thread(t1, "A"); //建立一個線程A Thread tb = new Thread(t1, "B"); //建立一個線程B ta.start();
tb.start();
} }oop

例二:當一個線程訪問object的一個synchronized(this)同步代碼塊時,另外一個線程仍然能夠訪問該object中的非synchronized(this)同步代碼塊。this

public class Test1 {線程

public void m4t1() {
	synchronized (this) {
		int i = 5;
		while (i-- > 0) {
			System.out.println(Thread.currentThread().getName() + " : " + i);

			try {
				Thread.sleep(500);// 睡眠半秒
			} catch (InterruptedException ie) {

			}
		}
	}
}

public void m4t2() {
	int i = 5;
	while (i-- > 0) {
		System.out.println(Thread.currentThread().getName() + " : " + i);
		try {
			Thread.sleep(500);// 睡眠半秒
		} catch (InterruptedException ie) {

		}
	}
}

public static void main(String[] args) {
	final Test1 myt2 = new Test1();
	Thread t1 = new Thread(new Runnable() {
		public void run() {
			myt2.m4t1();
		}
	}, "t1");
	Thread t2 = new Thread(new Runnable() {
		public void run() {
			myt2.m4t2();
		}
	}, "t2");
	t1.start();
	t2.start();
}

}code

例三:當一個線程訪問object的一個synchronized(this)同步代碼塊時,其餘線程對object中全部其它synchronized(this)同步代碼塊的訪問將被阻塞。 //修改Test1.m4t2()方法:
public void m4t2() {
synchronized(this) {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
} }對象

例四:當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就得到了這個object的對象鎖。結果,其它線程對該object對象全部同步代碼部分的訪問都被暫時阻塞。 //修改Thread2.m4t2()方法:
public void m4t2() {
synchronized(this) {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
} }接口

例五:以上規則對其它對象鎖一樣適用:(項目中使用過,更新玩家等級數據接口,定義一個對象,給它加鎖)get

private void m4t1(Inner inner) { synchronized(inner) { //使用對象鎖 inner.m4t1(); }同步

相關文章
相關標籤/搜索