线程安全-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

相关文章
相关标签/搜索