隨筆-95  評論-31  文章-10  trackbacks-0


          -Object類中有五個關于線程的方法:三個重載的wait()方法和notify()、notifyAll()
          問題1:為什么這些方法不定義在Thread類里面作為靜態方法使用?而是在Object類里面?

          這個問題先放下,先看線程狀態圖:

          new出一個線程后,處于Runnable狀態,獲得CPU控制權后執行,接著處于Running狀態,如果沒有控制,正常執行完畢會自動消亡即Dead。
          處于Running狀態的線程,第一:調用sleep或者join方法或者阻塞IO會進入阻塞狀態,一旦釋放會自動進入Runnable狀態。第二:調用wait方法會使線程處于等待池(是個對象池),一旦調用notify()或者interupt()方法線程會進入鎖池(是個對象池),然后就會進入Runnable狀態,等待CPU控制權。第三:運行中的線程進入synchronized方法或者synchronized代碼段,會進入鎖池,并且只有在synchronized里面才能調用wait()方法。

           1public Class MyStack
           2{
           3 private int[] a;
           4 private int MAX_SIZE;
           5 private int count;
           6
           7 public MyStack(){}
           8 public MyStack(int size)
           9{
          10   MAX_SIZE=size;
          11   a = new int[MAX_SIZE];
          12}
           
          13
          14  public synchronized void push()
          15{
          16    while(count==MAX_SIZE)
          17{
          18    try{
          19    this.wait();
          20    }
          catch(InterruptedException e)
          21{
          22}
             
          23}

          24    a[count++]=count;
          25    System.out.println(Thread.currentThread().getName():"當前線程增加一個數據后:"+count);
          26     this.notifyAll();
          27}

          28public synchronized int pop()
          29{
          30   while(count==0)
          31{   
          32try{
          33    this.wait();
          34   }
          catch(InterruptedException e)
          35{}
          36}
            
          37   this.notifyAll();
          38   System.out.println(Thread.currentThread().getName():"當前線程減少一個數據后:"+(count-1));
          39   return a[--count];
          40}

          41}

           

           1public Class Producer extends Thread
           2{
           3  private MyStack stack;
           4  public Producer(MyStack stack)
           5{
           6  this.stack= stack;
           7}

           8  @Override
           9  public void run()
          10{
          11  while(true)
          12{
          13   stack.push();
                   try{
                    Thread.sleep(200)
                   }catch(Exception e)
                  {}
          14}

          15}

          16}

           

          public Class Consumer extends Thread
          {
            
          private MyStack stack;
            
          public Consumer(MyStack stack)
          {
             
          this.stack=stack;
          }

            @Override
            
          public void run()
          {
            
          while(true)
          {
             stack.pop();
                   try{
                    Thread.sleep(200)
          }catch(Exception e)
                  {}

          }


          }


          }


          當調用push方法的時候,當前線程鎖定this對象,當棧滿了,開始調用wait()方法,使生產者線程處于等待池。當消費者線程通知生產者線程繼續生產的時候,wait()方法終結,如果使用if條件,并且處于多線程狀態(有若干個生產者線程),那么這個時候有可能另外一個處于鎖池狀態的線程開始執行,那么該線程會生產導致棧滿,而這個時候剛執行完wait()方法的線程也開始生產,那么會導致溢出。所以采用while循環,繼續判斷棧是否滿,如果不滿,那么執行生產,這個時候絕對不會出現任何問題,因為synchronized該線程獲得鎖,其余線程無法進入,必定安全。

          釋放對象的鎖:
          1、執行完同步代碼塊,就會釋放鎖
          2、執行同步代碼塊的過程中,執行了鎖所屬對象的wait()方法,這個線程會釋放鎖,進入對象的等待池。
          3、執行同步代碼塊的過程中,遇到異常而導致線程終止,鎖也會釋放

          不會釋放鎖:
          1、執行了Thread.sleep()方法,當前線程放棄CPU,開始睡眠,但不會釋放鎖。
          2、執行同步代碼塊的過程中,執行了Thread.yield()方法,當前線程放棄CPU但不會釋放鎖。

          posted on 2011-11-09 22:04 朔望魔刃 閱讀(223) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 桐庐县| 岢岚县| 宜兰市| 安福县| 青田县| 麦盖提县| 巴楚县| 南涧| 连云港市| 奇台县| 邯郸市| 桂林市| 岫岩| 南郑县| 区。| 板桥市| 阜平县| 昔阳县| 安仁县| 淄博市| 松桃| 六盘水市| 黎川县| 恭城| 黔江区| 奉贤区| 同德县| 连山| 沙洋县| 杨浦区| 崇信县| 临沭县| 五河县| 叙永县| 南宫市| 鸡东县| 德庆县| 开阳县| 日土县| 陆良县| 六枝特区|