java同步synchronized詳解

       synchronized能夠修飾代碼塊也能夠修飾方法,還能夠做用於靜態方法,類和某個實例java

       每一個對象都有一把鎖,當多個線程同時訪問共享資源的時候,須要用到synchronized,synchronized分爲代碼塊和方法,代碼塊須要顯示的指定對象,而方法不須要(即當前對象)。ide

        java的內存模型是對每個進程都有主內存,每一個線程也有本身的內存,它們從主內存中取數據,而後在計算,在存入主內存。函數

         例子:如今有兩個線程A,B線程,A線程對變量i加1,B線程同時對i加2,這兩個線程同時操做,若是沒有同步處理則B線程作的操做會覆蓋A線程的操做。this

         這時能夠用synchronized處理,synchronized具備原子性,原子操做:取數據,操做數據,存數據。synchronized能夠保證同一時間只有一個線程操做該對象。spa

        java中對非Long和Float原始數據類型的存,取爲原子操做。其實就是對一個字節的存,取操做,因爲Float和Long爲兩個字節,因此其取,存爲非原子操做。若是想把他們變成原子操做能夠用volatile.線程

        做用區域主要有兩種:code

        (1)、方法對象

        (2)、代碼塊進程

          對於用一對像的同步操做只能有一個線程,而對於不一樣對象是互不干擾的。
內存

  Public synchronized void change() {
     //同步方法
  }
  Public void change() { 
      Synchronized(this) {
          //同步語句:(由於效率問題,有時考慮使用同步語句塊)
      }
   }

   同步方法是針對當前對象的,若是不針對當前對象,而是針對其餘對象能夠用同步語句,如:

private byte[]  lock= new byte[0];
 
  Public void change() {
    Synchronized(lock) {
  }
}

自定義鎖注意:

   a、對象必須爲private防止其餘類對象訪問

   b、geter方法最好clone一個對象返回

其餘用法

      能夠針對靜態方法和類

Class Foo   {   
public synchronizedstatic void methodAAA()// 同步的static 函數  
{   
//….  
}  
  public void methodBBB()   {   
       synchronized(Foo.class)
             // class literal(類名稱字面常量) 
 } 
}

  它是針對整個類的,因此只能是同一個類的一個線程進行訪問

  synchronized(this)與synchronized(static class)的區別:

     synchronized就是針對內存區塊申請內存鎖,this是類的一個對象,也就是針對相同對象的互斥操做,其餘線程能夠訪問該類的其餘對象。static是針對類,static是整個類共有的,也就是該類的全部成員間互斥。在同一時間只有一個線程能夠訪問該類的實例。

創建三個線程,A線程打印10次A,B線程打印10次B,C線程打印10次C,要求線程同時運行,交替打印10次ABC。這個問題用Object的wait(),notify()就能夠很方便的解決。代碼以下:

public class MyThreadPrinter2 implements Runnable {     
    
    private String name;     
    private Object prev;     
    private Object self;     
    
    private MyThreadPrinter2(String name, Object prev, Object self) {     
        this.name = name;     
        this.prev = prev;     
        this.self = self;     
    }     
    
    @Override    
    public void run() {     
        int count = 10;     
        while (count > 0) {     
            synchronized (prev) {     
                synchronized (self) {     
                    System.out.print(name);     
                    count--;    
                      
                    self.notify();     
                }     
                try {     
                    prev.wait();     
                } catch (InterruptedException e) {     
                    e.printStackTrace();     
                }     
            }     
    
        }     
    }     
    
    public static void main(String[] args) throws Exception {     
        Object a = new Object();     
        Object b = new Object();     
        Object c = new Object();     
        MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);     
        MyThreadPrinter2 pb = new MyThreadPrinter2("B", a, b);     
        MyThreadPrinter2 pc = new MyThreadPrinter2("C", b, c);     
             
             
        new Thread(pa).start();  
        new Thread(pb).start();  
        new Thread(pc).start();    }     
}
相關文章
相關標籤/搜索