同步方法与同步块那个是更好选择

在java 开发中,我们在使用synchronized关键字对同步数据进行加锁时,有两种写法,一是同步方法,另一种时同步方法块。

代码如下:


/**
 * @author Evan Walker
 * @version 1.0
 * @desc 昂炎数据 https://www.ayshuju.com/home
 * @date 2023/03/23 22:22:50
 */
public class SynchronizeDemo {

    Object lock = new Object();

    /**
     * 第一种,锁住整个静态method 类锁(同步方法)
     */
    public static synchronized void synchronizedMethodA() {
        //业务代码
    }

    /**
     * 第一种相当于用类对象锁住代码块 类锁(同步代码块)
     */
    public static void synchronizedBlockA() {
        synchronized (SynchronizeDemo.class) {
            //业务代码
        }
    }

    /**
     * 第二种,使用一个互斥对象锁住代码块;它可以这么理解,多个线程想访问互斥代码块,必须拿到mutex对象的锁。
     * 然后,后面的所有类型都可以用第一种类型来解释(同步代码块)
     */
    public void synchronizedBlockB() {
        synchronized (lock) {
            // 业务代码
        }
    }

    /**
     * 第三种,锁住整个非静态method (同步方法)
     */
    public synchronized void synchronizedMethodC() {
        //业务代码
    }

    /**
     * 第三种相当于用this对象来锁住方法(同步代码块)
     */
    public void synchronizedBlockC() {
        synchronized (this) {
            //业务代码
        }
    }

}

上述代码描述了几种同步方法,和同步代码块的写法。

同步方法与同步块的区别

同步方法:同步方法直接在方法上加 synchronized 实现加锁。

同步方法块:同步代码块则在方法内部加锁,在起方法内部实现synchronized关键字。

同步方法与同步块那个是更好的选择?

同步代码块是更好的选择

因为它不会锁住整个对象(当然你也可以让它锁住整个对象),意味着同步块之外的代码是异步执行的,效率会更高。同步方法会锁住整个对象,哪怕这个类中有对各不相关联的同步块,这通常会导致他们停止执行并需要等待获取这个对象上的锁。

同步代码块更要符合开放调用原则,只在需要锁住的代码块锁住相应的对象,这样从侧面来说可以避免死锁。

请知道这样一条原则,同步的范围越小越好

但也有例外:Java锁粗化

虽说同步的范围越少越好,但在 Java 虚拟机中存在着一种叫做锁粗化的优化方法,这种方法是把同步范围变大。比方说 StringBuffer ,它是一个线程安全的类,自然最常用的 append() 方法是一个同步方法,写代码的时会反复 append 字符串,这意味着要进行反复的加锁 -> 解锁,这对性能不利,这意味着 Java 虚拟机在这条线程上要反复地在内核态和用户态之间进行切换,因此 Java 虚拟机会将多次 append 方法调用的代码进行一个锁粗化的操作,将多次的 append 的操作扩展到 append 方法的头尾,变成一个大的同步块,这样就减少了加锁 --> 解锁的次数,有效地提升了代码执行的效率。

更多消息资讯,请访问昂炎数据(https://www.ayshuju.com/home

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值