synchronized的4种用法

synchronized的4种用法

   1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.


     例如:

      publicsynchronized void synMethod() {

        //方法体

      }

   2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁.例如:

      public int synMethod(int a1){

       synchronized(a1){

           //一次只能有一个线程进入

         }

      }


   3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.例如:


 public class MyThread implements Runnable {

    public static void main(String args[]) {

    MyThread mt = new MyThread();

    Thread t1 = new Thread(mt, "t1");

    Thread t2 = new Thread(mt, "t2");

    Thread t3 = new Thread(mt, "t3");

    Thread t4 = new Thread(mt, "t4");

    Thread t5 = new Thread(mt, "t5");

    Thread t6 = new Thread(mt, "t6");

    t1.start();

    t2.start();

    t3.start();

    t4.start();

    t5.start();

    t6.start();

   }


  public void run() {

    synchronized (this) {

      System.out.println(Thread.currentThread().getName());

    }

   }

 }





    对于3,如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行.在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁,而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源,就不需要只为了让一个线程使用其中一部分资源,就将所有线程都锁在外面。由于每个对象都有锁,可以如下所示使用虚拟对象来上锁:


 class FineGrainLock {


   MyMemberClass x, y;

   Object xlock = new Object(), ylock = new Object();


   public void foo() {

      synchronized(xlock) {

         //access x here

      }


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


      synchronized(ylock) {

         //access y here

      }

    }


   public void bar() {

      synchronized(this) {

         //access both x and y here

      }

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

    }

   }




    4.synchronized后面括号里是类,此时,线程获得的是对象锁.例如:


 class ArrayWithLockOrder{

   privatestatic long num_locks = 0;

   privatelong lock_order;

   privateint[] arr;


   publicArrayWithLockOrder(int[] a)

   {

     arr = a;

    synchronized(ArrayWithLockOrder.class) {//-----这里

      num_locks++;             //锁数加 1。


      lock_order = num_locks;  //为此对象实例设置唯一的lock_order。

     }

   }

   publiclong lockOrder()

   {

     returnlock_order;

   }

   publicint[] array()

   {

     returnarr;

   }

   }


   classSomeClass implements Runnable

  {

   public intsumArrays(ArrayWithLockOrder a1,

                        ArrayWithLockOrder a2)

   {

     intvalue = 0;

     ArrayWithLockOrderfirst = a1;       //保留数组引用的一个

    ArrayWithLockOrder last = a2;       //本地副本。

     int size= a1.array().length;

     if (size== a2.array().length)

     {

       if(a1.lockOrder() > a2.lockOrder())  //确定并设置对象的锁定

       {                                     //顺序。

        first = a2;

         last= a1;

       }

      synchronized(first) {             //按正确的顺序锁定对象。

        synchronized(last) {

          int[] arr1 = a1.array();

          int[] arr2 = a2.array();

          for (int i=0; i

            value += arr1[i] + arr2[i];

         }

       }

     }

     returnvalue;


   }

   publicvoid run() {

     //

   }

   }




    对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁. 这样的同步块而言,所有调用Test多个实例的线程赐教只能有一个线程可以执行.

你可能感兴趣的:(synchronized的4种用法)