java怎么使用同步数据_java中synchronized的用法具体怎么使用?

小伙伴们是否知道什么是synchronized吗?的确,翻译过来就是同步。那我们为什么使用同步呢?在Java中java是如何使用synchronized的呢?让我们一起了解下吧。

1.如何在Java中使用synchronized块。

简单地说,在多线程环境中,当两个或多个线程同时尝试更新可变共享数据时,就会发生竞争条件。Java提供了一种通过同步对共享数据的线程访问来避免竞争条件的机制。标记为synchronized的逻辑变为同步块,在任何给定时间只允许一个线程执行。

2.为什么同步?

让我们考虑一个典型的竞争条件,我们计算总和,多个线程执行calculate()方法:

de9bde72d6a28b785d360557ebaad959.png

让我们写一个简单的测试:

a02c174792422b6539278954f983d517.png

我们只是使用带有3线程池的ExecutorService来执行1000次计算()。

如果我们按顺序执行,预期的输出将是1000,但我们的多线程执行几乎每次都会失败,实际输出不一致,例如:

b810a060e165c2f3e89d03f387cb197f.png

这个结果当然不是意料之外的。

避免竞争条件的一种简单方法是使用synchronized关键字使操作成为线程安全的。

3. 同步关键字

该同步关键字可以以不同级别被使用:

· 实例方法

· 静态方法

· 代码块

当我们使用synchronized块时,内部Java使用监视器(也称为监视器锁或内部锁)来提供同步。这些监视器绑定到一个对象,因此同一对象的所有同步块只能有一个线程同时执行它们。

3.1 Synchronized实例方法

只需在方法声明中添加synchronized关键字即可使方法同步:

27f38aa1e17ed924195c94266541513a.png

请注意,一旦我们同步该方法,测试用例就会通过,实际输出为1000:

8d2ddce7c6f822709db742743ebe264d.png

实例方法在拥有该方法的类的实例上同步。这意味着每个类的实例只能有一个线程可以执行此方法。

3.2 Synchronized static方法

静态方法与实例方法一样是同步的:

be90f743c568afbd9dd5ee8148dc71a7.png

这些方法在与该类关联的Class对象上同步,并且由于每个JVM每个类只存在一个Class对象,因此每个类只能在一个静态同步方法内执行一个线程,而不管它具有多少个实例。

我们来试试吧:

3c8527e85883be6d2a813ba8fa17b4d9.png

3.3 方法中的同步块

有时我们不想同步整个方法,只需要同步其中的一些指令。这可以通过将 synchronized应用于块来实现:

08ded917ce50b9e87b9e5f8098ef2d9f.png

让我们测试一下这个变化:

eb00e297ecf7401a4a3f433fb6504056.png

请注意,我们将参数this传递给synchronized块。这是监视器对象,块内的代码在监视器对象上获得同步。简而言之,每个监视器对象只能在该代码块内执行一个线程。

如果方法是静态的,我们将传递类名来代替对象引用。该类将成为块同步的监视器:

2a8a50cd56c7c3d50584871f0016d0cf.png

让我们在静态方法中测试块:

43fe415623bf5efaa21223d4ed35e951.png

以上就是对java中synchronized的用法的总结,是否对synchronized有了更多的了解呢?想要了解跟多知识,请继续关注本站。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值