1. 程式人生 > >java synchronized 內建鎖理解

java synchronized 內建鎖理解

synchronized的用法:站在物件鎖和類鎖的角度分析
物件鎖和類鎖的區別:

public  class SynchronizedClass {

    public synchronized void method(){
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"我是物件鎖");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void method1(){
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"我是物件鎖1");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static synchronized void method2(){
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"我是類鎖");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public  void method3(){
        synchronized (SynchronizedClass.class) {
            for(int i=0;i<5;i++){
                System.out.println(Thread.currentThread().getName()+"我是類鎖1");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedClass synchronizedClass = new SynchronizedClass();
        SynchronizedClass synchronizedClass1 = new SynchronizedClass();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method1();     //同一物件執行結果同步
//              synchronizedClass1.method1();  //不同物件執行結果非同步


            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method2();     //類鎖和物件鎖非同步
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method3();
            }
        }).start();
    }
}

1)多個執行緒訪問同一物件的的同步程式碼時,只有一個執行緒能獲取物件鎖,其他的執行緒不能訪問這個物件任何地方使用synchronized 修飾的程式碼必須等待或者阻塞,直到前面的執行緒釋放鎖,其他執行緒才能重新競爭鎖。
2)多個執行緒訪問不同物件的同步程式碼時,是互不干擾的,程式碼會非同步執行
3)物件鎖和類鎖是互不干擾的,程式碼會非同步執行

物件鎖,鎖的是類的物件例項。
寫法有兩種:
1)直接修飾方法

public synchronized void method(){
        System.out.println("我是物件鎖");
    }

2)修飾程式碼塊

public void method(){
		//dosomething  業務程式碼
		synchronized(this){
			System.out.println("我是物件鎖");
		}//一個執行緒訪問該物件的這個方法時候,另一個執行緒可以同時執行這個物件這個方法沒用synchronized的程式碼
	}

兩種寫法都是物件鎖,一個是鎖整個方法,一個是鎖方法中的一部分程式碼,當一個執行緒訪問一個物件的同步程式碼時候,其他執行緒訪問同一個物件的其他沒用synchronized修飾的方法或方法中的程式碼時,會非同步執行。

類鎖 ,一個抽象出來的概念,鎖的是每個類的的Class物件,每個類的的Class物件在一個虛擬機器中只有一個,所以類鎖也只有一個。規則和物件鎖一致
寫法有兩種:
1)靜態方法

public static synchronized void method(){
        System.out.println("我是類鎖");
}

2)

   public void method(){
		synchronized (類名.class) {
			System.out.println("我是第二種類鎖");
		}
	}