线程不安全的类型

2021年10月23日补充。

线程不安全类型条件 == 共享 || 可变

共享:线程间共享,Java的堆是共享的,对象在堆上创建,所以一般对象都是共享的。(例外:JDK里的LocalVariabl; Flutter 单线程模型,堆不进行共享)

可变:(mutable),先说什么是 不可变:例如final修饰,或者 String。只要一改动,就重新 赋值,而不是直接改变。

线程原子性实用分类:

看《JAVA并发编程实践》关于线程不安全类型,有个很有趣且实用的分类:

分类:

1.检查执行(check then execute)

典型的就是单例模式(要求全局只有一个对象)

public static synchronized Instance getInstance(){
  if(instance == null){
    instance = new Instance();
  }
  return instance;
}

如果不加synchronized,且 instance为空时:

在instance==null这个检查点上A线程停止(还没有执行到instance = new Instance()),B线程运行,A、B都会判断为true,然会返回两个对象,违反单例模式。

2.读改写(read change write)

  这个典型的就是生产者-消费者模式了。即使方法内是原子性操作,可两个方法在两个线程下混合调用也可能有问题。

  如使用Vector线程安全类(读操作,写操作本身是原子性操作不会出问题),a线程调用aA()方法读最后元素,b线程调用bB()方法删除最后元素。

  

  aA()方法:得到Vector的size--》读取index == size-1的元素。

  bB()方法:得到Vector的size--》删除index == size-1的元素,size--

  条件:Vector对象假设size == 5.

  

  执行过程:a线程得到size等于5,线程暂停运行-》

                      b线程运行,得到size等于5  --》

                      删除index == 4的元素,size--(size == 4,最后元素index == 3),b线程终止-》

                      a线程读取index ==  4,索引越界报错。

这个时候就用 synchronized(lock){},给aA()、bB()方法内部加锁,lock是随便一个对象了。保证aA()、bB()方法调用互斥(即一个执行,另一个绝对不能执行)。

总结:

  简单来说 就是原子性操作的两种情景。上文说的那本书也不错,可以了解很多java并发包下的知识,简化并发编程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值