您的位置:网站首页 > Java教程 > 正文

Java 多线程三大核心点实例

类别:Java教程 日期:2019-7-25 5:13:23 人气: 来源:

  JMM 只是了基本的原子性,但类似于 i++ 之类的操作,看似是原子操作,其实里面涉及到:

  这三步操作,所以想要实现 i++ 这样的原子操作就需要用到 synchronize 或者是 lock 进行加锁处理。

  如果是基础类的自增操作可以使用 AtomicInteger 这样的原子类来实现(其本质是利用了 CPU 级别的 的 CAS 指令来完成的)。

  首先是获得当前的值,然后自增 +1。接着则是最核心的 compareAndSet() 来进行原子更新。

  其逻辑就是判断当前的值是否被更新过,是否等于 current,如果等于就说明没有更新过然后将当前的值更新为 next,如果不等于则返回lse 进入循环,直到更新成功为止。

  我刚整理了一套2018最新的0基础入门和进阶教程,分享,加Java学习q-u-n :六七八,二四一,五六三 即可获取,内附:开发工具和安装包,以及系统学习线图

  还有其中的 get() 方法也很关键,返回的是当前的值,当前值用了 volatile 关键词修饰,了内存可见性。

  现代计算机中,由于 CPU 直接从主内存中读取数据的效率不高,所以都会对应的 CPU 高速缓存,先将主内存中的数据读取到缓存中,线程修改数据之后首先更新到缓存,王学兵和范冰冰之后才会更新到主内存。如果此时还没有将数据更新到主内存其他的线程此时来读取就是修改之前的数据。

  volatile 关键字就是用于内存可见性,当线程A更新了 volatile 修饰的变量时,它会立即刷新到主线程,并且将其余缓存中该变量的值清空,导致其余线程只能去主内存读取最新值。

  使用 volatile 关键词修饰的变量每次读取都会得到最新的数据,不管哪个线程对这个变量的修改都会立即刷新到主内存。

  synchronize和加锁也能能可见性,实现原理就是在锁之前其余线程是访问不到这个共享变量的。但是和 volatile 相比开销较大。

  正常情况下的执行顺序应该是 123。但是有时 JVM 为了提高整体的效率会进行指令重排导致执行的顺序可能是 213。但是 JVM 也不能是什么都进行重排,是在最终结果和代码顺序执行结果一致的情况下才可能进行重排。

  Java 中可以使用 volatile 来顺序性,synchronize 和 lock 也可以来有序性,和原子性的方式一样,通过同一段时间只能一个线程访问来实现的。

  除了通过 volatile 关键字显式的顺序之外, JVM 还通过 happen-before 原则来隐式的顺序性。

  其中有一条就是适用于 volatile 关键字的,针对于 volatile 关键字的写操作肯定是在读操作之前,也就是说读取的值肯定是最新的。

  分配内存空间。(1) 初始化对象。(2) 将 singleton 对象指向分配的内存地址。(3)

  加上 volatile 是为了让以上的三步操作顺序执行,反之有可能第二步在第三步之前被执行就有可能某个线程拿到的单例对象是还没有初始化的,以致于报错。

  这里如果没有用 volatile 来修饰 flag ,就有可能其中一个线程调用了 stop()方法修改了 flag 的值并不会立即刷新到主内存中,导致这个循环并不会立即停止。

  财成国际

关键词:java多线程
0
0
0
0
0
0
0
0
下一篇:没有资料

网友评论 ()条 查看

姓名: 验证码: 看不清楚,换一个

推荐文章更多

热门图文更多

最新文章更多

关于联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助

郑重声明:本站资源来源网络 如果侵犯了你的利益请联系站长删除

CopyRight 2010-2012 技术支持 FXT All Rights Reserved