線程安全-002-多個線程多把鎖&類鎖

1、多個對象多把鎖

例子代碼:ide

package com.lhy.thread01; public class MultiThread { //static
    private int num = 0; //加上static後就是類級別的鎖。不加,是對象級別的鎖,此時多個線程之間是互不干擾
    public synchronized  void printNum(String tag){ try{ if("a".equals(tag)){ num = 100; System.out.println("tag a ,set num over!"); Thread.sleep(1000);//a會睡1秒,b不會
            }else{ num = 200; System.out.println("tag b ,set num over!"); } System.out.println("tag "+ tag +" , num = "+ num); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args) { //兩個不一樣的對象
        final MultiThread m1 = new MultiThread(); final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() { @Override public void run() { m1.printNum("a"); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { m2.printNum("b"); } }); t1.start(); t2.start(); } }

執行結果:spa

關鍵字synchornized得到的鎖是對象鎖,哪一個線程先執行synchornized關鍵字的方法,哪一個線程就持有該方法所屬對象的鎖,例子程序中,因爲m1和m2是兩個不一樣的對象,t1 線程得到 m1對象的鎖,t2線程得到m2對象的鎖,因此互不影響。線程

驗證, 若是將main方法改成以下所示,t1 和 t2 線程都執行m1對象的printNum方法,此時兩個線程在搶一把鎖,因此執行會按順序來:3d

public static void main(String[] args) {
        //兩個不一樣的對象
        final MultiThread m1 = new MultiThread();
        //final MultiThread m2 = new MultiThread();
        
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
               m1.printNum("a");
            }
        });
        
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
               m1.printNum("b");
            }
        });
        
        t1.start();
        t2.start();
    }

 

2、多個對象一把鎖(類鎖)

 在靜態方法上加上synchornized關鍵字,表示鎖定.class類,類一級別的鎖(獨佔.class 類)code

例子程序:對象

public class MultiThread {
    
    //static
    private static int num = 0;
    
    //加上static後就是類級別的鎖。不加,是對象級別的鎖,此時多個線程之間是互不干擾
    public static synchronized  void printNum(String tag){
        try{
            if("a".equals(tag)){
                num = 100;
                System.err.println("tag a ,set num over!");
                Thread.sleep(1000);//a會睡1秒,b不會
            }else{
                num = 200;
                System.err.println("tag b ,set num over!");
            }
            System.err.println("tag "+ tag +" , num = "+ num);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        //兩個不一樣的對象
        final MultiThread m1 = new MultiThread();
        final MultiThread m2 = new MultiThread();
        
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                m1.printNum("a");
            }
        });
        
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                m2.printNum("b");
            }
        });
        
        t1.start();
        t2.start();
    }

}

執行結果:blog

是按照t一、t2 順序執行的。io

相關文章
相關標籤/搜索