Java_synchronized的鎖對象之對象鎖和類鎖

具體知識學習與

https://blog.csdn.net/yansuoo/article/details/51248281

https://www.jianshu.com/p/6586d9f3b515

下面是自己的理解+代碼:

一.前置知識:

       java的對象鎖和類鎖:java的對象鎖和類鎖在鎖的概念上基本上和內置鎖是一致的,但是,兩個鎖實際是有很大的區別的,對象鎖是用於對象實例方法,或者一個對象實例上的,類鎖是用於類的靜態方法或者一個類的class對象上的。我們知道,類的對象實例可以有很多個,但是每個類只有一個class對象,所以不同對象實例的對象鎖是互不干擾的,但是每個類只有一個類鎖。但是有一點必須注意的是,其實類鎖只是一個概念上的東西,並不是真實存在的,它只是用來幫助我們理解鎖定實例方法和靜態方法的區別的

二.代碼理解

  1. synchronized(對象鎖):兩種;
  2. synchronized(this){ 
    //互斥代碼
    } 
    或:
    private Object lock = new Object();
    public void test1(){
        synchronized(lock){ 
        //互斥代碼
        }
    }
    

    這裏的this,指的是調用它的實例對象,即鎖就是這個這裏對象 ; 而lock鎖則是任意對象鎖(所有需要這個對象的鎖的方法都不能同時執行),有些許的不同(所有線程線程能共用該鎖)。

  3. 代碼:

    Ticket t1=new Ticket();   Ticket t2=new Ticket(); Ticket t3=new Ticket();
    t1.start();     t2.start();   t3.start();
    //測試三個線程 	   
    class Ticket extends Thread{
        private int num=100;
        //Object obj = new Object();
        public void run() {
    	while(true) {
                //synchronized (obj) 
                synchronized (this) {
                   if(num>0)System.out.println(Thread.currentThread().getName()+".."+num--);                  
    	        try {
    		    Thread.sleep(100);
    		}catch (Exception e) {}
    	    }
    		System.out.println(Thread.currentThread().getName()+":釋放");
            }
        }
    }

    此時線程1.2.0.交替執行,但注意下一次線程1.2.0像執行必須對應鎖釋放,換句話說這裏三個線程對象對應了三個鎖,只鎖自己,不能鎖別人,cpu可以切換其他線程執行,只要沒被鎖。  而代碼註釋的第二種結果是:                  與上面同理,也是隻能鎖自己。是把當前這個對象的成員變量(object)當做鎖,其實三個線程對象有三個不同的object對象,因爲這個變量不共享。

  4. tips:這樣加鎖的好處 (這是最常用的高併發場景下要鎖住某個方法所用的操作) :如果這時用synchronized來修飾代碼塊:synchronized(obj){obj.testsy();},那麼這個方法加鎖的對象是obj這個對象,跟執行這行代碼的對象沒有關係,當一個線程執行這個方法時,這對其他同步方法時沒有影響的,因爲他們持有的鎖都完全不一樣。

    private Object lock = new Object();
    public void test1(){
        synchronized(lock){ 
        //互斥代碼
        }
    }
    

     

  5. private static Object lock = new Object();

    但如果任意對象鎖改爲靜態的,則可以實現互斥了,所有線程共享這個鎖(共享這個變量)。                                       

  6. synchronized(類鎖)

  7. 對於類鎖來說其實和對象鎖一樣只是爲了區別靜態方法和普通方法,對於多個線程,都是一把鎖,和第5點的情況一樣

    synchronized(A.class){ 
    //互斥代碼
    }
    

    tips:object.getClass()和A.class實際意義不同,並且對於前者來說,出現多態時,可能會有問題

  8. 每個線程執行都得等內閣唯一的一把鎖釋放。

三:一點解釋:

    Thread.sleep():強制線程休眠未來*ms時間內不進入CPU進行競爭,進入阻塞狀態,給其他線程機會執行,但是,他不會釋放鎖;且 *毫秒過去之後,這時候也許另外一個線程正在使用CPU,那麼這時候操作系統是不會重新分配CPU的, 直到那個線程掛起或結束;況且,即使這個時候恰巧輪到操作系統進行CPU 分配,那麼當前線程也不一定就是總優先級最高的那個,CPU還是可能被其他線程搶佔去。也不一定會論到調度他。

    線程獲得對象鎖的同時,也可以獲得該類鎖,即同時獲得兩個鎖,這是允許的。

 

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