当前位置:网站首页 > Java教程 > 正文

java教程synchronized



廖雪峰
资深软件开发工程师,业余马拉松选手。

我们知道Java程序依靠对线程进行同步,使用的时候,锁住的是哪个对象非常重要。

让线程自己选择锁对象往往会使得代码逻辑混乱,也不利于封装。更好的方法是把逻辑封装起来。例如,我们编写一个计数器如下:

这样一来,线程调用、方法时,它不必关心同步逻辑,因为代码块在、方法内部。并且,我们注意到,锁住的对象是,即当前实例,这又使得创建多个实例的时候,它们之间互不影响,可以并发执行:

现在,对于类,多线程可以正确调用。

如果一个类被设计为允许多线程正确访问,我们就说这个类就是“线程安全”的(thread-safe),上面的类就是线程安全的。Java标准库的也是线程安全的。

还有一些不变类,例如,,,它们的所有成员变量都是,多线程同时访问时只能读不能写,这些不变类也是线程安全的。

最后,类似这些只提供静态方法,没有成员变量的类,也是线程安全的。

除了上述几种少数情况,大部分类,例如,都是非线程安全的类,我们不能在多线程中修改它们。但是,如果所有线程都只读取,不写入,那么是可以安全地在线程间共享的。

我们再观察的代码:

当我们锁住的是实例时,实际上可以用修饰这个方法。下面两种写法是等价的:

写法二:

因此,用修饰的方法就是同步方法,它表示整个方法都必须用实例加锁。

我们再思考一下,如果对一个静态方法添加修饰符,它锁住的是哪个对象?

对于方法,是没有实例的,因为方法是针对类而不是实例。但是我们注意到任何一个类都有一个由JVM自动创建的实例,因此,对方法添加,锁住的是该类的实例。上述方法实际上相当于:

我们再考察的方法:

它没有同步,因为读一个变量不需要同步。

然而,如果我们把代码稍微改一下,返回一个包含两个的对象:

就必须要同步了。

用修饰方法可以把整个方法变为同步代码块,方法加锁对象是;

通过合理的设计和数据封装可以让一个类变为“线程安全”;

一个类没有特殊说明,默认不是thread-safe;

多线程能否安全访问某个非线程安全的实例,需要具体问题具体分析。

版权声明


相关文章:

  • 新版java安装教程2025-01-15 13:10:06
  • java 单元测试教程2025-01-15 13:10:06
  • 442集java教程2025-01-15 13:10:06
  • java编码教程免费2025-01-15 13:10:06
  • java接口在线教程2025-01-15 13:10:06
  • java基础画图教程2025-01-15 13:10:06
  • java104编程教程2025-01-15 13:10:06
  • java编辑语句教程2025-01-15 13:10:06
  • java17安装教程2025-01-15 13:10:06
  • 菜鸟教程java异常2025-01-15 13:10:06