细论Synchronize的使用区别

细论Synchronize的使用区别

Synchronize的作用

在并发编程中实现共享数据的同步。

Synchronize使用形式

Synchronize的使用方式大体分为两种:Synchronize同步方法 以及 Synchronize块。其本质都是对目标对象(或类)的锁定,让该方法变为原子操作

Synchronize同步方法

Synchronize同步方法的使用上大致也分为两种情况:修饰普通方法,与修饰静态方法

Synchronize修饰普通方法
先谈谈修饰普通方法,当我们给一个普通方法加上Synchronize修饰词。此时,该方法即能实现同步。我们用不同的线程去跑这个方法时,同一时间,只能有一个线程进入该方法。保证了共享资源的安全性。

public synchronized void Something_A()

但是这里有几个注意点

  1. 在用多线程去跑该同步方法时,须注意改同步方法是否是来自于同一个实例对象。因为同步方法是属于对象的,不同的对象的同步方法并不是同一个同步方法,也就意味着线程获取的锁,并不是同一把锁。以至于线程并不能实现同步。
  2. 同一个类中如果有多个Synchronize修饰的方法,那么当一个线程获取了一个方法的锁后,其他线程并不能进入该类中任意Synchronize修饰的方法(除静态方法)。这也说明了Synchronize锁的对象,在同步方法与静态方法时不同的。(下面一段我会讲到Synchronize修饰普通方法与修饰静态方法的不同。)

Synchronize修饰静态方法

public synchronized static void Something_B()

与Synchronize修饰普通方法一样。修饰静态方法也是让多线程实现同步。当有线程获取锁后,其他线程便不能进入Synchronize修饰的静态方法。

那么其与Synchronize修饰的普通方法有什么不同呢?其实很简单,Synchronize修饰方法其实是对类或者对象加锁。当Synchronize修饰普通方法时,是对当前对象(this)加锁,而当其修饰静态方法时,是对类进行加锁。这一点很重要,也是对后面理解Synchronize块有帮助的。

所以针对上文的注意点,Synchronize修饰静态方法也有一些注意点

  1. 因为其修饰的是静态方法,而静态方法是属于类本身的。而无论实例化多少个对象,该类依旧只有一个。所以,如果线程跑的不是一个实例化对象的静态同步方法,也会有同步的效果。因为Synchronize是对该类上锁。
  2. 而为什么前文提到的某一线程获取Synchronize修饰的普通方法后,其他依旧可以进入Synchronize修饰的静态方法,原因不言而喻。前者获取的是实例化对象的锁,而后者获取的是类的锁

对于Synchronize修饰同步方法,就先讲到这里。
其实在在使用时,我们会出现一种情况。例如当一条线程进入Synchronize后,对其中的属性A进行长时间的操作。而另一条线程在此期间想对属性B进行短时间操作,但因为Synchronize修饰的原因,只能排队等待。
这并不符合我们的逻辑,因为对于属性A的更改与对属性B的更改并不需要同步,但我们为了防止其他线程进入更改该线程的进入本方法,所以又不得不使用Synchronize。所以这种时候我们便可以使用Synchronize块。

Synchronize块

在了解了Synchronize修饰方法后,我们其实很容易再理解Synchronize块的应用。其原理就是对我需要锁定的对象或类上锁。而这里我们也可以再细化出三种情况:

Synchronize修饰非this对象
此时Synchronize锁定的便只是指定的该对象。例如上面所说的例子中,我们便可以使用如下方法提高同步的性能:

public void Something_A()
{
    synchronized (A)
    {
        //此处为对A的操作。
    }
}

public void Something_B()
{
    synchronized (B)
    {
        //此处为对B的操作。
    }
}

因为两个Synchronize所锁定的不是同一个对象,所以在某一线程进入Something_A()的Synchronize块时,其他线程依旧可以进入Something_B()中的Synchronize块。

Synchronize修饰this对象
该原理与Synchronize块修饰普通方法相同,是对本对象的锁定。故其性质也与之前的Synchronize修饰普通方法相同。

synchronized (this)
{
    
}

Synchronize修饰class
该原理与Synchronize块修饰静态方法相同,是对类的锁定。故其性质也与之前的Synchronize修饰静态方法相同。

synchronized (this.class)
{
    
}
//当然也可以延伸出下面的形式
synchronized (Object.class) // object为任意对象
{
    
}

总结

  1. Synchronize的作用是针对并发编程,实现同步。
  2. Synchronize的本质是对对象或类上锁,而不是对于某一方法上锁
  3. 在判断线程是否同步时,我们即可根据上文的方法观察线程是否在争抢同一把锁
  4. 在使用Synchronize时,我们应注意使用volatile关键字实现数据的同步。
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ryan kk

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

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

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

打赏作者

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

抵扣说明:

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

余额充值