1. 程式人生 > >類鎖和物件鎖,synchronized修飾static方法與非static方法的區別

類鎖和物件鎖,synchronized修飾static方法與非static方法的區別

類鎖物件鎖,synchronized修飾static方法與非static方法的區別

 當synchronized修飾一個static方法時,多執行緒下,獲取的是類鎖(即Class本身,注意:不是例項),

       作用範圍是整個靜態方法,作用的物件是這個類的所有物件。

 當synchronized修飾一個非static方法時,多執行緒下,獲取的是物件鎖(即類的例項物件),

       作用範圍是整個方法,作用物件          是呼叫該方法的物件

       結論: 類鎖和物件鎖不同,它們之間不會產生互斥

例子:synchronized修飾static方法與非static方法的區別

public class test_類鎖與物件鎖的區別 extends Thread{
      public static int i = 0;
      public static int j = 0;
      public synchronized void inc(){
            i ++;
      }
      public static synchronized void incs(){
            j ++;
      }
      public void run() {
            for (int x = 0; x < 10; x++) {
                  inc();
                  incs();
                  try {
                        Thread.sleep(33);
                  } catch (InterruptedException e) {
                        e.printStackTrace();
                  }
            }
      }
      public static void main(String[] args) throws InterruptedException {
             //不使用定執行緒池 
            Thread[] t = new Thread[100];
            for (int i = 0; i < t.length; i++) {
                  t[i] = new test_類鎖與物件鎖的區別();
            }
            for (int i = 0; i < t.length; i++) {
                  t[i].start();
            }
            for (int i = 0; i < t.length; i++) {
                  t[i].join();
            }
            System.out.println("synchronized修飾非靜態方法----"+test_類鎖與物件鎖的區別.i);
            System.out.println("synchronized修飾靜態方法----"+test_類鎖與物件鎖的區別.j);
      }
}

效果:

例子:synchronized修飾static方法與非static方法,物件鎖的解決方案

public class test_類鎖與物件鎖_解決方案 {
      public static int i = 0;
      public static int j = 0;
       //synchronized修飾非靜態方法
    public  synchronized void function() throws InterruptedException {
        i++;
    }
    //synchronized修飾靜態方法
    public static synchronized void staticFunction()
            throws InterruptedException {
       j++;
    }
      public static void main(String[] args) {
            final test_類鎖與物件鎖_解決方案 demo = new test_類鎖與物件鎖_解決方案();
            //使用定長執行緒池
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {                     
                        staticFunction();
                        demo.function();
                        Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        for (int i = 0; i < 1000; i++) {
             fixedThreadPool.execute(t1);
            }    
        fixedThreadPool.shutdown();
        while(true){
                  if (fixedThreadPool.isTerminated()) { 
                          System.out.println("synchronized修飾非靜態方法----"+test_類鎖與物件鎖_解決方案.i);
                          System.out.println("synchronized修飾靜態方法----"+test_類鎖與物件鎖_解決方案.j);
                        break;
                  }
       }   
      }
}

效果: