多线程理解

一、为什么学习多线程技术

  • 因为并发是整个分布式集群的基础,通过分布式集群不仅可以大大降低同等负载能力的价格,还能使整体可扩展到的负载能力上限大大提升。大多数抽象并发问题的构思与解决都是基于多线程模型来进行的。而且这些并发问题的本质都是相同的,不管是指令级并发、线程并发还是服务器级别的并发都具有类似的特点、面临相似的问题,多线程编程正是我们切入这个领域、学习并发问题解决方案的最好途径。而分布式也有些像是多线程的放大版,所以理解多线程问题的解决思想才是“道”。

二、多线程数据安全问题

  • 由来:对性能的追求而导致的编程复杂程度增加。

    先看操作系统内存模型如何优化:
    1、cpu、内存、I/O 设备三者的速度差异。
    解决办法:增加了缓存,以均衡速度差异。
    引入新问题:缓存一致性问题(可见性问题
    在这里插入图片描述
    2、充分利用处理器内部的运算单元 。
    解决办法:处理器可能会对代码进行乱序执行优化
    引入新问题:指令重排序(一致性问题)
    3、处理器需要做别的事 。
    解决办法:可切换
    引入新问题:返回时共享数据可能已被修改(原子性问题

    再看JAVA的“Java内存模型”与“操作系统内存模型”十分类似,也存在这三方面问题,当然这个模型也是JAVA跨平台的基础。
    在这里插入图片描述
    三、JAVA虚拟机提供的基本解决方案

(1)原子性(Atomicity)
Java代码中可用synchronized关键字保证操作的原子性。
(2)可见性(Visibility)
可见性就是指当一个线程修改了共享变量的值时,其他线程能够立即得知这个修改。
Java代码中可用synchronized关键字、volatile变量、final字段保证可见性。
(3)有序性(Ordering)
Java语言提供了volatile和synchronized两个关键字来保证线程之间操作的有序性,禁止指令重排序。

四、java.util.concurrent提供的高效工具类

  • 并发编程可类比成一群人完成一项任务,每个人都是一个线程。这群人之间的关系(按是否协作、是否共享数据)分三种情况。

    情况一:不协作,不共享(不互斥)
    创建线程,执行各自任务即可。例:在大数据项目中各区县创建一个线程进行数据处理。
    情况二:协作,不共享(不互斥)
    创建线程,执行各自任务并在合适地方使用同步工具类进行协作。例:在大数据量实时查询时利用Fork/Join框架将线程查询的数据汇集合并。
    情况三:协作,共享(互斥)
    创建线程,执行各自任务在共享变量处要进行互斥防止出现数据问题。
    而JUC包为实现这样的思想提供工具,开发者利用工具做三件事:分解任务、线程协作、共享资源互斥
    在这里插入图片描述
    整个JUC包的内容:
    在这里插入图片描述
    五、举个栗子
    目的:应用JMM深入理解为什么类的一般成员变量是不安全的?进一步理解为什么struts2必须是多例的而springmvc是单例的?
    在这里插入图片描述
    在这段代码中count值就是两个线程的共享资源累加后数据小于20000证明是不安全的。
    下图JVM实际内存模型:
    在这里插入图片描述
    在这里插入图片描述
    类比到JMM模型此变量属于主存中内容,所以是不安全的多线程访问需要同步操作。
    回忆struts2的数据接收方式是属性驱动或模型驱动,同一个对象这部分数据也是多线程共享的,所以多线程访问需要多例。而springmvc用方法接收参数,方法在虚拟机栈中是线程私有的,所以是单例。内存占用较多可能也是struts2逐渐被springmvc取代的原因。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值