隨筆-88  評論-77  文章-48  trackbacks-0

          對synchronized(this)的一些理解
          ?
          一、當兩個并發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以后才能執行該代碼塊。

          ?

          二、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。

          ?

          三、尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

          ?

          四、第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。

          ?

          五、以上規則對其它對象鎖同樣適用.

          ?

          舉例說明:

          ?

          一、當兩個并發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以后才能執行該代碼塊。

          ?

          package ths;

          public class Thread1 implements Runnable {
          public void run() {
          synchronized(this) {
          for (int i = 0; i < 5; i++) {
          System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
          }
          }
          }
          public static void main(String[] args) {
          Thread1 t1 = new Thread1();
          Thread ta = new Thread(t1, "A");
          Thread tb = new Thread(t1, "B");
          ta.start();
          tb.start();
          }
          }

          ?

          結果:

          ?

          A synchronized loop 0
          A synchronized loop 1
          A synchronized loop 2
          A synchronized loop 3
          A synchronized loop 4
          B synchronized loop 0
          B synchronized loop 1
          B synchronized loop 2
          B synchronized loop 3
          B synchronized loop 4

          ?

          二、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。

          ?

          package ths;

          public class Thread2 {
          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 Thread2 myt2 = new Thread2();
          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();
          }
          }

          ?

          結果:

          ?

          t1 : 4
          t2 : 4
          t1 : 3
          t2 : 3
          t1 : 2
          t2 : 2
          t1 : 1
          t2 : 1
          t1 : 0
          t2 : 0

          ?

          三、尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

          ?

          //修改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) {
          }
          }
          }

          }

          ?

          結果:

          ?

          t1 : 4
          t1 : 3
          t1 : 2
          t1 : 1
          t1 : 0
          t2 : 4
          t2 : 3
          t2 : 2
          t2 : 1
          t2 : 0

          ?

          四、第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。

          ?

          //修改Thread2.m4t2()方法如下:

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

          ?

          結果:

          ?

          t1 : 4
          t1 : 3
          t1 : 2
          t1 : 1
          t1 : 0
          t2 : 4
          t2 : 3
          t2 : 2
          t2 : 1
          t2 : 0

          ?

          五、以上規則對其它對象鎖同樣適用:

          ?

          package ths;

          public class Thread3 {
          class Inner {
          private void m4t1() {
          int i = 5;
          while(i-- > 0) {
          System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
          try {
          Thread.sleep(500);
          } catch(InterruptedException ie) {
          }
          }
          }
          private void m4t2() {
          int i = 5;
          while(i-- > 0) {
          System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
          try {
          Thread.sleep(500);
          } catch(InterruptedException ie) {
          }
          }
          }
          }
          private void m4t1(Inner inner) {
          synchronized(inner) { //使用對象鎖
          inner.m4t1();
          }
          }
          private void m4t2(Inner inner) {
          inner.m4t2();
          }
          public static void main(String[] args) {
          final Thread3 myt3 = new Thread3();
          final Inner inner = myt3.new Inner();
          Thread t1 = new Thread(
          new Runnable() {
          public void run() {
          myt3.m4t1(inner);
          }
          }, "t1"
          );
          Thread t2 = new Thread(
          new Runnable() {
          public void run() {
          myt3.m4t2(inner);
          }
          }, "t2"
          );
          t1.start();
          t2.start();
          }
          }

          ?

          結果:

          盡管線程t1獲得了對Inner的對象鎖,但由于線程t2訪問的是同一個Inner中的非同步部分。所以兩個線程互不干擾。

          ?

          t1 : Inner.m4t1()=4
          t2 : Inner.m4t2()=4
          t1 : Inner.m4t1()=3
          t2 : Inner.m4t2()=3
          t1 : Inner.m4t1()=2
          t2 : Inner.m4t2()=2
          t1 : Inner.m4t1()=1
          t2 : Inner.m4t2()=1
          t1 : Inner.m4t1()=0
          t2 : Inner.m4t2()=0

          ?

          現在在Inner.m4t2()前面加上synchronized:

          ?

          private synchronized void m4t2() {
          int i = 5;
          while(i-- > 0) {
          System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
          try {
          Thread.sleep(500);
          } catch(InterruptedException ie) {
          }
          }
          }

          ?

          結果:

          盡管線程t1與t2訪問了同一個Inner對象中兩個毫不相關的部分,但因為t1先獲得了對Inner的對象鎖,所以t2對Inner.m4t2()的訪問也被阻塞,因為m4t2()是Inner中的一個同步方法。

          ?

          t1 : Inner.m4t1()=4
          t1 : Inner.m4t1()=3
          t1 : Inner.m4t1()=2
          t1 : Inner.m4t1()=1
          t1 : Inner.m4t1()=0
          t2 : Inner.m4t2()=4
          t2 : Inner.m4t2()=3
          t2 : Inner.m4t2()=2
          t2 : Inner.m4t2()=1
          t2 : Inner.m4t2()=0

          posted on 2006-07-19 10:55 崛起的程序員 閱讀(313) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 开江县| 洮南市| 义乌市| 顺昌县| 太原市| 巴南区| 卢湾区| 永顺县| 布尔津县| 富蕴县| 定州市| 乐安县| 阿坝县| 思茅市| 班戈县| 剑阁县| 云阳县| 丰都县| 慈溪市| 军事| 安图县| 杭锦旗| 洛隆县| 海伦市| 共和县| 绥宁县| 沭阳县| 丹巴县| 柳江县| 建昌县| 云龙县| 景东| 通河县| 五华县| 斗六市| 太原市| 延吉市| 平原县| 陆丰市| 盐边县| 芦山县|