java中synchronized的用法具体怎么使用?

2020-03-27 20:40:57 java常见问答 7621

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

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

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

2.为什么同步?

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

java中synchronized的用法

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

java中synchronized的用法

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

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

java中synchronized的用法

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

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

3. 同步关键字

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

· 实例方法

· 静态方法

· 代码块

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

3.1 Synchronized实例方法

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

java中synchronized的用法

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

java中synchronized的用法

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

3.2 Synchronized static方法

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

1.png

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

我们来试试吧:

java中synchronized的用法

3.3 方法中的同步块

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

java中synchronized的用法

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

java中synchronized的用法

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

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

java中synchronized的用法

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

java中synchronized的用法

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