当前位置: 首页 > news >正文

java 多线程

引:1946年 第一台计算机 ENIAC 诞生,一个时间段只能执行一个任务。

Q:为什么同时一时间只能执行一个任务呀,任务在执行IO操作的时候,CUP完全可以做其它事情嘛。

A:那个搞个进程吧,每个任务一个进程,这个就可以一个进程做IO时,一个进程用cup。

Q:这样好是好,但是有的时候一个任务里有多个事情要做,而这些事情没有先后关系,能不能把这些事情也同时做?

A:呃,可以呀,再搞个线程吧,把进程再拆一下,每个事情对应一个线程,他们相互独立运行,不是就可以了。

        于是大家开开心心的用着多个线程,后来慢慢的发现,多个线路会存在共享资源的情况(即多个线程之单不是完全的独立的),而对这共享资源的使用经常出现莫名其妙的问题,比如:原资源数为0,A线程对资源+1,B线程也对资源+1, 资源有的时候结果为1,而不是为2,这是为什么呢?

       原来呀,java把内线分为了主存和工作内存,主存由多个线程共享,工作内存由线程独,每个线程对应有自己的工作内存,线程执行时,会先将主存中的资源值复制到工作内存,在工作内存中运行完成后,再将运行完产生的新值复制到主存中。

       这样,当B线程去获取主存中的资源时,由于不知道A线程对资源的修改情况,可能会拿到原始值(0),因此在原始值上做+1操作,所以资源是加了2次,但结果还是1。

      那么java为什么要把内存分为主存和工作内存呢?

       这个可以参考机器的内存--->高速缓存/寄存器---->CPU的设计。

       原因是知道了,但要怎么解决这个问题呢? 思来想去,大家觉得只要保存原子性、可见性和有序性就能保证多个线程操作的正确性。

       原子性:做一件可要么全部做完,要么不要做。

       可见性:做一件事,A已经把这个件事做了,当B要去做的时候要知道已经有人做过了,这时如果B还要做,那就可以在被A做过的基础上再做了。

        有序性:程序执行的顺序按照代码的先后顺序执行。(因为编译器会对代码进行指令重排序,以提高cpu的性能,所以程序的执行与代码的顺序会存在不一致的性,但编译器能保证在单线程的情况下重排序后的执行结果与代码的顺序执行的结果一致)

 那么如何保证原子性、可见性和有序性呢?

      加锁:保护一个代码片段,使这个代码片段在同一时间永远只有一个线程执行。即改线程的并行操作为串行操作。

     一致性协议:

那么有哪些锁,有哪些加锁操作呢?

       共享锁:同时可以有多个线程可以获取,每次唤醒多个等待着。

       独占锁:同时只有一个线程可以获取,每次只能唤醒一个等待着。

       公平模式:先到先得,非常公司。

  非公平模式:来的时候不排序,先试一把,成功了就用,不成功就老实排序。

  死锁 :

       重入锁: 已获得锁的线程可以再次获得这个锁。

       非重入锁:已获得锁的线程可以再次获得这个锁

      

      加锁操作:synchronized  & AQS(Mutex、ReentrantLock、Semaphore、cyclicbarrier、CountDownLatch)  & atomic(CAS、volatile)

       volatile:编译器通过为指令加lock前缀来防止重排序,保证有序性,同时它的本身的机制可以保证可见性。但不能保证原子性。

       CAS:利用处理器提供的CMPXCHG指令实现的,而处理器执行CMPXCHG指令是一个原子性操作。

       AQS:https://www.cnblogs.com/dolphin0520/p/3920397.html   、https://www.cnblogs.com/waterystone/p/4920797.html

 

      线程状态:http://www.cnblogs.com/waterystone/p/4920007.html

       线程池:https://www.cnblogs.com/dongguacai/p/6030187.html

      

     

 

转载于:https://www.cnblogs.com/movemoon/p/10320459.html

相关文章:

  • .NET Core IdentityServer4实战-开篇介绍与规划
  • Matplotlib中plt.rcParams用法(设置图像细节)
  • 14-tail-and-head-commands-linuxunix
  • Apollo的Oracle适配改动
  • 甄姬
  • Sql 排序
  • contest3 CF994 div2 ooxxx? oooox? ooooo?
  • 梯度下降算法对比(批量下降/随机下降/mini-batch)
  • Angular CLI的简单使用(2)
  • 最大团优化
  • 02-jQuery的选择器
  • Aria2 使用手札(简易部署 + 快速进阶)
  • 『The Captain 最短路建图优化』
  • 各种编码格式转换
  • Kali学习笔记40:SQL手工注入(2)
  • [数据结构]链表的实现在PHP中
  • 【Leetcode】104. 二叉树的最大深度
  • Apache的80端口被占用以及访问时报错403
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • CSS居中完全指南——构建CSS居中决策树
  • JavaScript函数式编程(一)
  • JavaScript学习总结——原型
  • Mocha测试初探
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • MySQL用户中的%到底包不包括localhost?
  • Node + FFmpeg 实现Canvas动画导出视频
  • Spark学习笔记之相关记录
  • SpiderData 2019年2月16日 DApp数据排行榜
  • SpiderData 2019年2月25日 DApp数据排行榜
  • vue学习系列(二)vue-cli
  • 测试开发系类之接口自动化测试
  • 解析 Webpack中import、require、按需加载的执行过程
  • 开发基于以太坊智能合约的DApp
  • 深入 Nginx 之配置篇
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • ![CDATA[ ]] 是什么东东
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (12)Linux 常见的三种进程状态
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (WSI分类)WSI分类文献小综述 2024
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (转)http-server应用
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .Net 高效开发之不可错过的实用工具
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • @Transient注解
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [EFI]Dell Latitude-7400电脑 Hackintosh 黑苹果efi引导文件
  • [exgcd] Jzoj P1158 荒岛野人