synchronized 对象锁和类锁的区别详细

synchronized 是一个关键字。

synchronized 加到 static 方法前面是给class 加锁,即类锁;
synchronized 加到非静态方法上是给对象上锁,即对象锁。

对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。

所以我们用代码来演示下

 

首先准备工作,先创建一个Task类 新建三个方法其中两个 是static修饰静态的。

/**
 * @Title: dmdemo
 * @Description:
 * @author: liaryank
 * @Date: 2020/7/23 1:37 下午
 * @Version: 1.0
 */
public class Task {
    public synchronized static void TaskA() {
        System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
    }

    public synchronized static void TaskB() {
        System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
    }

    public synchronized void TaskC() {

        System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");

    }

第二步 创建三个类来调用各自Task中的方法(也就像IG   baolan说:“各过各的”)咱们各调各的。

/**
 * @Title: dmdemo
 * @Description:
 * @author: liaryank
 * @Date: 2020/7/23 2:00 下午
 * @Version: 1.0
 */
public class ThreadA extends Thread{
    private Task TTask;

    public ThreadA(Task tk){
        TTask = tk;
    }

    public void run() {
        TTask.TaskA();
    }
}


/**
 * @Title: dmdemo
 * @Description:
 * @author: liaryank
 * @Date: 2020/7/23 1:46 下午
 * @Version: 1.0
 */
public class ThreadB extends Thread{

    private Task TTask;

    public ThreadB(Task tk){
        TTask = tk;
    }

    public void run() {
        TTask.TaskB();
    }

}


/**
 * @Title: dmdemo
 * @Description:
 * @author: liaryank
 * @Date: 2020/7/23 2:01 下午
 * @Version: 1.0
 */
public class ThreadC extends Thread{

    private Task TTask;

    public ThreadC(Task tk){
        TTask = tk;
    }

    public void run() {
        TTask.TaskC();
    }
}

第三步创建一个main方法咱们来测试一下

 public static void main(String[] args) {
        Task TTask = new Task();
        ThreadA ta = new ThreadA(TTask);
        ThreadB tb = new ThreadB(TTask);
        ThreadC tc = new ThreadC(TTask);
        
        ta.setName("A");
        tb.setName("B");
        tc.setName("C");

        ta.start();
        tb.start();
        tc.start();
    }

结果如下,我们可以清楚的看到TaskA和TaskB是顺序执行的,而TaskC是和TaskA、TaskB异步执行的。因为TaskA、TaskB是加了static修饰的属于类锁,TaskC是对象锁。

我们来继续测试,测试同步调用TaskC 看看TaskC会不会顺序执行,我们修改ThreadA和ThreadB,让这两个都去调用TaskC方法

 然后咱们main也要改下如下

public static void main(String[] args) {

        Task TTaska = new Task();
        Task TTaskb = new Task();
        ThreadA ta = new ThreadA(TTaska );
        ThreadB tb = new ThreadB(TTaskb );


        ta.setName("A");
        tb.setName("B");

        ta.start();
        tb.start();
}

 结果如下,可以看出 ThreadA和ThreadB在调用方法锁TaskC时是异步执行的。

 

测试完了方法锁,咱们在试试类锁

将ThreadA和ThreadB中调用方法都改成调用TaskA。mian方法不用变执行即可。

/**
 * @Title: dmdemo
 * @Description:
 * @author: liaryank
 * @Date: 2020/7/23 2:00 下午
 * @Version: 1.0
 */
public class ThreadA extends Thread{
    private Task TTask;

    public ThreadA(Task tk){
        TTask = tk;
    }

    public void run() {
        TTask.TaskA();
    }
}



/**
 * @Title: dmdemo
 * @Description:
 * @author: liaryank
 * @Date: 2020/7/23 1:46 下午
 * @Version: 1.0
 */
public class ThreadB extends Thread{

    private Task TTask;

    public ThreadB(Task tk){
        TTask = tk;
    }

    public void run() {
        TTask.TaskA();
    }

}

 执行结果如下,从结果我们可以看出,方法上加了静态static 成为类锁后会顺序执行。

我们来小小总结一下:

  1. 类锁对该类的所有对象都能起作用,而对象锁不能。

  2. 多线程访问某类中synchronized修饰的静态和非静态方法时是可以异步执行的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值