synchronized 關鍵字

synchronized 做用

  可以保證在同一時刻最多隻有一個線程執行該段代碼,以達到併發安全的效果java

synchronized的2種用法

對象鎖:包括方法鎖(默認鎖對象爲this當前實例對象)和同步代碼塊鎖(本身指定鎖對象)

代碼塊形式:

/**
 * @Description: 對象鎖之一,同步代碼塊鎖
 */
public class Demo1 implements Runnable {
    // 實例
    static Demo1 instance = new Demo1();
    // 自定義對象鎖
    Object lock1 = new Object();
    Object lock2 = new Object();

    public void run() {
        synchronized (lock1) {
            System.out.println("對象鎖的同步代碼塊,鎖lock1,線程名稱:"
                    + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("lock1,"+Thread.currentThread().getName() + "運行結束!");
        }
        synchronized (lock2) {
            System.out.println("對象鎖的同步代碼塊,鎖lock2,線程名稱:"
                    + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("lock2,"+Thread.currentThread().getName() + "運行結束!");
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {
        }
        System.out.println("finished");
    }
}

運行結果以下:

方法鎖形式:

/**
 * @Description: 對象鎖之二,方法鎖
 */
public class Demo2 implements Runnable{
    static  Demo2 instance = new Demo2();

    public void run() {
        method();
    }

    public synchronized  void method(){
        System.out.println("對象鎖的方法修飾符形式,名稱:"
                +Thread.currentThread().getName()
        );
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "運行結束!");
    }

    public static void main(String[] args){
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()){

        }
        System.out.println(
                "finished!"
        );
    }
}
運行結果以下:

 

類鎖:指synchronized修飾靜態的方法或指定鎖爲class對象

1.只有一個class對象:java類可能會有不少個對象,可是隻有1個class對象安全

  2.本質:因此所謂類鎖,不過是class對象的鎖而已併發

  3.用法和效果:類鎖只能在同一時刻被一個對象所擁有this

靜態方法形式:

 

/**
 * @Description: 類鎖之一,static形式
 */
public class Demo3 implements Runnable{
    static  Demo3 instance1 = new Demo3();
    static  Demo3 instance2 = new Demo3();
    public void run() {
        method();
    }

    public static synchronized  void method(){
        System.out.println("類鎖,名稱:"
                +Thread.currentThread().getName()
        );
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "運行結束!");
    }

    public static void main(String[] args){
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()){}
        System.out.println("finished!");
    }
}
運行結果以下:

 

 *.class形式:

/**
 * @Description: 類鎖之二:synchronized(.*)形式
 */
public class Demo4 implements Runnable {
    static Demo4 instance1 = new Demo4();
    static Demo4 instance2 = new Demo4();
    public void run() {
       method();
    }

    private void method(){
        synchronized (Demo4.class) {
            System.out.println("類鎖,synchronized(.*)形式,名稱:"
                    + Thread.currentThread().getName()
            );
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "運行結束!");
        }
    }

    public static void main(String[] args){
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()){}
        System.err.println("finished!");
    }
}
運行結果以下:
相關文章
相關標籤/搜索