[Java] synchronized在代码块中修饰.class与this的区别

    synchronized是java中的关键字,表示同步,可以在多线程环境中起到锁的作用。它是jvm层面的锁,不需要人为获取释放锁资源,由jvm决定。

    synchronized可以直接用在方法上,这种用法和synchronized在代码块中修饰this是一样的。

    synchronized也可以直接用在static静态方法上,这种用法和synchronized在代码块中修饰.class类似,说类似是因为代码块粒度更小一些。

    它也可以用在代码块中,这时候它可以修饰一个类对象.class,一个全局对象lock,或者this。

     一般我们关注的就是修饰.class和this的区别。

     修饰.class,就是表示多线程调用该类的不管什么实例,所有实例共用一把锁。

     修饰this,多线程调用该类的实例,如果每个线程都有一个实例,那么每个实例都有各自的锁,他们互相不影响。如果多线程去竞争一个实例,那么这个锁就只有一把,多线程去争一个资源。

    下面通过一个示例来看看他们的区别:

package com.xxx.lock;
import java.util.Date;
public class SynchronizedExample {
    public static void main(String[] args) {
        for(int i=0;i<5;i++){
            BusinessService businessService = new BusinessService();
            new BusinessThread(businessService).start();
        }
    }

    static class BusinessService{
        public void action(){
            synchronized (BusinessService.class){
                try {
                    System.out.println(Thread.currentThread().getName()+" running at "+new Date());
                    Thread.sleep(1000);
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }
    }

    static class BusinessThread extends Thread{
        BusinessService businessService;
        public BusinessThread(BusinessService businessService){
            this.businessService = businessService;
        }

        @Override
        public void run() {
            businessService.action();
        }
    }
}

    运行结果:

Thread-0 running at Mon Oct 10 22:32:49 CST 2022
Thread-4 running at Mon Oct 10 22:32:50 CST 2022
Thread-3 running at Mon Oct 10 22:32:51 CST 2022
Thread-2 running at Mon Oct 10 22:32:52 CST 2022
Thread-1 running at Mon Oct 10 22:32:53 CST 2022

    从结果可以看出,多线程调用synchronized(.class)修饰的代码块时,无论线程调用的对象实例是一个,还是多个,最终只有一个线程进入同步代码块。其他线程等待资源释放再运行。

    这个地方,如果synchronized修饰this:

    结果是这样的:

Thread-3 running at Mon Oct 10 22:37:41 CST 2022
Thread-2 running at Mon Oct 10 22:37:41 CST 2022
Thread-4 running at Mon Oct 10 22:37:41 CST 2022
Thread-1 running at Mon Oct 10 22:37:41 CST 2022
Thread-0 running at Mon Oct 10 22:37:41 CST 2022

    五个线程几乎同时执行,因为他们各自调用的是不同的实例,而每个实例都有自己的锁,与其他实例互不干扰。

    这个代码其实可以修改,就是线程创建的时候,指定对象实例为同一个。

    这个时候运行结果就是多线程竞争一把锁,线程依次交替执行:

Thread-0 running at Mon Oct 10 22:50:23 CST 2022
Thread-4 running at Mon Oct 10 22:50:24 CST 2022
Thread-3 running at Mon Oct 10 22:50:25 CST 2022
Thread-2 running at Mon Oct 10 22:50:26 CST 2022
Thread-1 running at Mon Oct 10 22:50:27 CST 2022

    这个时候,把synchronized修饰符改为修饰.class,结果也是一样的,线程交替执行。

    从上面的示例,我们可以知道,要想多线程竞争一把锁,我们使用synchronized修饰.class、this都是可以的,但是在使用this的时候,需要注意,如果我们传递给线程的实例各不相同,那么最终同步代码块之间互不干扰 ,就没有同步的作用了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值