Java 并发系列(一):多线程三大特性

概述多线程三大特性:原子性、可见性、有序性。1. 原子性原子性是指:多个操作作为一个整体,不能被分割与中断,也不能被其他线程干扰。如果被中断与干扰,则会出现数据异常、逻辑异常。多个操作合并的整体,我们称之为复合操作。一个复合操作,往往存在前后依赖关系,后一个操作依赖上一个操作的结果。如果上一个操作结果被其他线程干扰,对于当前线程看来整个复合操作的结果便不符合预期。同理线程也不能在复合操作中间被中断,中断必须发生在进入复合操作之前或者等到复合操作结束之后。保证原子性就是在多线程环境下,保证
摘要由CSDN通过智能技术生成

概述

多线程三大特性:原子性、可见性、有序性。

1. 原子性

原子性是指:多个操作作为一个整体,不能被分割与中断,也不能被其他线程干扰。如果被中断与干扰,则会出现数据异常、逻辑异常。

多个操作合并的整体,我们称之为复合操作。一个复合操作,往往存在前后依赖关系,后一个操作依赖上一个操作的结果。如果上一个操作结果被其他线程干扰,对于当前线程看来整个复合操作的结果便不符合预期。同理线程也不能在复合操作中间被中断,中断必须发生在进入复合操作之前或者等到复合操作结束之后。

保证原子性就是在多线程环境下,保证单个线程执行复合操作符合预期逻辑。

典型的复合操作:『先检查后执行』和『读取—修改—写入』

1.1 先检查后执行

@NotThreadSafe
public class LazyInitClass {
	private static LazyInitClass instance ;

	public static LazyInitClass getInstance() {
		if(instance == null)
			instance = new LazyInitClass() ;

		return instance ;
	}
}

LazyInitClassgetInstance 中包含先检查后执行的复合操作,通常我们也可以称 getInstance 中包含竞态条件。假设线程 A 和线程 B 同时执行 getInstance。A 看到 instance 为空,便执行 new LazyInitClass() 逻辑。A 还未完成初始化并设置 instance,B 检查 instance,此时 instance 为空,B 便也会执行 new LazyInitClass()。那么两次调用 getInstance 时可能会得到不同的结果。通常 getInstance 的预期结果是多次调用得到相同的对象实例。

LazyInitClassgetInstance 方法虽然存在竞态条件,多数情况下并不会造成业务异常,影响仅仅是增加了 JVM 垃圾回收负担而已。这也是多线程问题隐蔽性强且偶发的原因之一。

但话说回来,编程原则之一就是所有逻辑都必须建立在确定性之上,任何建立在不确定性上的逻辑都是隐患。虽然从业务上看多数情况下没问题,但竞态条件的存在,让代码逻辑建立在不确定性之上。作为编码者应该重视此类问题。

1.2 读取—修改—写入

@NotThreadSafe
public class ReadModifyAndWriteClass {
	private int count = 0 ;

	public int increase() {
		return count++ 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值