synchronized的4種用法

  1.方法聲明時使用,放在範圍操作符(public等)之後,返回類型聲明(void等)之前.這時,線程獲得的是成員鎖,即一次只能有一個線程進入該方法,其他線程要想在此時調用該方法,只能排隊等候,當前線程(就是在synchronized方法內部的線程)執行完該方法後,別的線程才能進入.
 
      例如:

ExpandedBlockStart.gif      public synchronized void synMethod() {
InBlock.gif        //方法體
ExpandedBlockEnd.gif
      }

    2.對某一代碼塊使用,synchronized後跟括號,括號裏是變量,這樣,一次只有一個線程進入該代碼塊.此時,線程獲得的是成員鎖.例如:

ExpandedBlockStart.gif      public int synMethod(int a1){
ExpandedSubBlockStart.gif        synchronized(a1) {
InBlock.gif          //一次只能有一個線程進入
ExpandedSubBlockEnd.gif
        }

ExpandedBlockEnd.gif      }


    3.synchronized後面括號裏是一對象,此時,線程獲得的是對象鎖.例如:

 

ExpandedBlockStart.gif public class MyThread implements Runnable {
ExpandedSubBlockStart.gif    public static void main(String args[]) {
InBlock.gif    MyThread mt = new MyThread();
InBlock.gif    Thread t1 = new Thread(mt, "t1");
InBlock.gif    Thread t2 = new Thread(mt, "t2");
InBlock.gif    Thread t3 = new Thread(mt, "t3");
InBlock.gif    Thread t4 = new Thread(mt, "t4");
InBlock.gif    Thread t5 = new Thread(mt, "t5");
InBlock.gif    Thread t6 = new Thread(mt, "t6");
InBlock.gif    t1.start();
InBlock.gif    t2.start();
InBlock.gif    t3.start();
InBlock.gif    t4.start();
InBlock.gif    t5.start();
InBlock.gif    t6.start();
ExpandedSubBlockEnd.gif  }

InBlock.gif
ExpandedSubBlockStart.gif  public void run() {
ExpandedSubBlockStart.gif    synchronized (this{
InBlock.gif      System.out.println(Thread.currentThread().getName());
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}
 
None.gif 
None.gif
None.gif

 
    對於3,如果線程進入,則得到當前對象鎖,那麼別的線程在該類所有對象上的任何操作都不能進行.在對象級使用鎖通常是一種比較粗糙的方法。爲什麼要將整個對象都上鎖,而不允許其他線程短暫地使用對象中其他同步方法來訪問共享資源?如果一個對象擁有多個資源,就不需要只爲了讓一個線程使用其中一部分資源,就將所有線程都鎖在外面。由於每個對象都有鎖,可以如下所示使用虛擬對象來上鎖:

 

ExpandedBlockStart.gif class FineGrainLock {
InBlock.gif
InBlock.gif   MyMemberClass x, y;
InBlock.gif   Object xlock = new Object(), ylock = new Object();
InBlock.gif
ExpandedSubBlockStart.gif   public void foo() {
ExpandedSubBlockStart.gif      synchronized(xlock) {
InBlock.gif         //access x here
ExpandedSubBlockEnd.gif
      }

InBlock.gif
InBlock.gif      //do something here - but don't use shared resources
InBlock.gif

ExpandedSubBlockStart.gif      synchronized(ylock) {
InBlock.gif         //access y here
ExpandedSubBlockEnd.gif
      }

ExpandedSubBlockEnd.gif   }

InBlock.gif
ExpandedSubBlockStart.gif   public void bar() {
ExpandedSubBlockStart.gif      synchronized(this{
InBlock.gif         //access both x and y here
ExpandedSubBlockEnd.gif
      }

InBlock.gif      //do something here - but don't use shared resources
ExpandedSubBlockEnd.gif
   }

ExpandedBlockEnd.gif  }

None.gif
None.gif


     4.synchronized後面括號裏是類,此時,線程獲得的是對象鎖.例如:

 

ExpandedBlockStart.gifclass ArrayWithLockOrder{
InBlock.gif  private static long num_locks = 0;
InBlock.gif  private long lock_order;
InBlock.gif  private int[] arr;
InBlock.gif
InBlock.gif  public ArrayWithLockOrder(int[] a)
ExpandedSubBlockStart.gif  {
InBlock.gif    arr = a;
ExpandedSubBlockStart.gif    synchronized(ArrayWithLockOrder.class{//-----這裏
InBlock.gif
      num_locks++;             // 鎖數加 1。
InBlock.gif

InBlock.gif      lock_order = num_locks;  // 爲此對象實例設置唯一的 lock_order。
ExpandedSubBlockEnd.gif
    }

ExpandedSubBlockEnd.gif  }

InBlock.gif  public long lockOrder()
ExpandedSubBlockStart.gif  {
InBlock.gif    return lock_order;
ExpandedSubBlockEnd.gif  }

InBlock.gif  public int[] array()
ExpandedSubBlockStart.gif  {
InBlock.gif    return arr;
ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif  }

None.gif
None.gif  
class SomeClass implements Runnable
ExpandedBlockStart.gif 
{
InBlock.gif  public int sumArrays(ArrayWithLockOrder a1,
InBlock.gif                       ArrayWithLockOrder a2)
ExpandedSubBlockStart.gif  {
InBlock.gif    int value = 0;
InBlock.gif    ArrayWithLockOrder first = a1;       // 保留數組引用的一個
InBlock.gif
    ArrayWithLockOrder last = a2;        // 本地副本。
InBlock.gif
    int size = a1.array().length;
InBlock.gif    if (size == a2.array().length)
ExpandedSubBlockStart.gif    {
InBlock.gif      if (a1.lockOrder() > a2.lockOrder())  // 確定並設置對象的鎖定
ExpandedSubBlockStart.gif
      {                                     // 順序。
InBlock.gif
        first = a2;
InBlock.gif        last = a1;
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockStart.gif      synchronized(first) {              // 按正確的順序鎖定對象。
ExpandedSubBlockStart.gif
        synchronized(last) {
InBlock.gif          int[] arr1 = a1.array();
InBlock.gif          int[] arr2 = a2.array();
InBlock.gif          for (int i=0; i<size; i++)
InBlock.gif            value += arr1[i] + arr2[i];
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif    }

InBlock.gif    return value;
InBlock.gif
ExpandedSubBlockEnd.gif  }

ExpandedSubBlockStart.gif  public void run() {
InBlock.gif    //dot.gif
ExpandedSubBlockEnd.gif
  }

ExpandedBlockEnd.gif  }

None.gif
None.gif

  
    對於4,如果線程進入,則線程在該類中所有操作不能進行,包括靜態變量和靜態方法,實際上,對於含有靜態方法和靜態變量的代碼塊的同步,我們通常用4來加鎖.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章