天天看點

Synchronized代碼詳解?

synchronized是java的關鍵字,他有以下特性。

互斥性:同一個時間隻允許一個線程擷取到某個對象鎖,這樣就可以保證線程安全,同一時間隻有一個線程可以對代碼進行通路操作。互斥性也就是我們經常說的原子性。

可見性:必須保證在鎖被釋放前,對資料的修改 對其他線程是可見的,否則其他線程從其他地方擷取資料導緻不一緻性。

synchronized是隐式鎖,是jvm内置鎖,不需要手動加鎖與解鎖,jvm會自動加鎖跟解鎖。

而lock則需要實作lock接口,需要手動加鎖和解鎖。

下面代碼執行個體從三個方面進行加鎖。

  1. 靜态方法,鎖的是類對象。
  2. 普通方法,鎖的是執行個體對象。

(需要注意:在spring容器中,bean是單執行個體,否則加synchronized沒什麼意義)

  1. 代碼塊:鎖的是括号裡的對象。
/**
 * @author keying
 */
public class Synchronized822 {

    public static void main(String[] args) throws InterruptedException {
        ThreadTestNei threadTestNei = new ThreadTestNei();
        ThreadA threadA = new ThreadA(threadTestNei);
        threadA.setName("A-THREAD");
        threadA.start();

        ThreadB threadB = new ThreadB(threadTestNei);
        threadB.setName("B-THREAD");
        threadB.start();

    }

}

class ThreadA extends Thread {

    private ThreadTestNei threadTestNei;

    ThreadA(ThreadTestNei threadTestNei) {
        this.threadTestNei = threadTestNei;
    }

    @Override
    public void run() {
        super.run();
        threadTestNei.setUser();
    }
}

class ThreadB extends Thread {

    private ThreadTestNei threadTestNei;

    ThreadB(ThreadTestNei threadTestNei) {
        this.threadTestNei = threadTestNei;
    }

    @Override
    public void run() {
        super.run();
        threadTestNei.setUser();
    }
}

@Data
class ThreadTestNei {

    private String name;
    private String aString = new String();

    public void setUser() {
        try {
            synchronized (aString) {
                System.out.println(Thread.currentThread().getName() + "----" + "begin");
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + "----" + "end");
            }
        } catch (Exception e) {

        }

    }
}      

這時候他們修飾的是同一個對象,是以 輸出是

A-THREAD----begin
A-THREAD----end
B-THREAD----begin
B-THREAD----end      
try {
            String aString = new String();
            synchronized (aString) {
                System.out.println(Thread.currentThread().getName() + "----" + "begin");
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + "----" + "end");
            }
        } catch (Exception e) {

        }      
A-THREAD----begin
B-THREAD----begin
A-THREAD----end
B-THREAD----end      
try {
            synchronized (ThreadTestNei.class) {
                System.out.println(Thread.currentThread().getName() + "----" + "begin");
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + "----" + "end");
            }
        } catch (Exception e) {

        }      
A-THREAD----begin
A-THREAD----end
B-THREAD----begin
B-THREAD----end