
多线程
文章平均质量分 91
Franco蜡笔小强
小码农
展开
-
深入分析CAS
CAS,Compare And Swap,即比较并交换。Doug lea大神在同步组件中大量使用CAS技术鬼斧神工地实现了Java多线程的并发操作。整个AQS同步组件、Atomic原子类操作等等都是以CAS实现的,甚至ConcurrentHashMap在1.8的版本中也调整为了CAS+Synchronized。可以说CAS是整个JUC的基石。在CAS中有三个参数:内存值V、旧的预期值A、要更新的值B,当且仅当内存值V的值等于旧的预期值A时才会将内存值V的值修改为B,否则什么都不干。其伪代码如下:if(th转载 2022-06-23 11:23:40 · 1403 阅读 · 1 评论 -
Java内存模型之happens-before
由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题。那么我们正确使用同步、锁的情况下,线程A修改了变量a何时对线程B可见?我们无法就所有场景来规定某个线程修改的变量何时对其他线程可见,但是我们可以指定某些规则,这规则就是happens-before,从JDK 5 开始,JMM就使用happens-before的概念来阐述多线程之间的内存可见性。happens-before原则非常重要,它是判断数据是否存在竞争、线程是否安全的主要依据,依靠这个原则,我们解决在并发环境下两操作转载 2022-06-23 11:15:59 · 1011 阅读 · 0 评论 -
Java内存模型之重排序
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件:在单线程环境下不能改变程序运行的结果;存在数据依赖关系的不允许重排序如果看过LZ上篇博客的就会知道,其实这两点可以归结于一点:无法通过happens-before原则推导出来的,JMM允许任意的排序。as-if-serial语义的意思是,所有的操作均可以为了优化而被重排序,但是你必须要保证重排序后执行的结果不能被改变,编译器、runtime、处理器都必须遵守as-if-s转载 2022-06-23 11:13:46 · 1007 阅读 · 0 评论 -
深入分析CAS
CAS,Compare And Swap,即比较并交换。Doug lea大神在同步组件中大量使用CAS技术鬼斧神工地实现了Java多线程的并发操作。整个AQS同步组件、Atomic原子类操作等等都是以CAS实现的,甚至ConcurrentHashMap在1.8的版本中也调整为了CAS+Synchronized。可以说CAS是整个JUC的基石。CAS分析在CAS中有三个参数:内存值V、旧...转载 2019-04-10 17:34:26 · 240 阅读 · 0 评论 -
J.U.C之Java并发容器:ConcurrentHashMap
此篇博客所有源码均来自JDK 1.8HashMap是我们用得非常频繁的一个集合,但是由于它是非线程安全的,在多线程环境下,put操作是有可能产生死循环的,导致CPU利用率接近100%。为了解决该问题,提供了Hashtable和Collections.synchronizedMap(hashMap)两种解决方案,但是这两种方案都是对读写加锁,独占式,一个线程在读时其他线程必须等待,吞吐量较低...转载 2018-12-05 20:43:44 · 237 阅读 · 0 评论 -
深入源码分析Java线程池的实现原理
程序的运行,其本质上,是对系统资源(CPU、内存、磁盘、网络等等)的使用。如何高效的使用这些资源是我们编程优化演进的一个方向。今天说的线程池就是一种对CPU利用的优化手段。网上有不少介绍如何使用线程池的文章,那我想说点什么呢?我希望通过学习线程池原理,明白所有池化技术的基本设计思路。遇到其他相似问题可以解决。池化技术前面提到一个名词——池化技术,那么到底什么是池化技术呢?池化技术简...转载 2018-10-08 15:19:01 · 546 阅读 · 0 评论 -
J.U.C之Condition
在没有Lock之前,我们使用synchronized来控制同步,配合Object的wait()、notify()系列方法可以实现等待/通知模式在没有Lock之前,我们使用synchronized来控制同步,配合Object的wait()、notify()系列方法可以实现等待/通知模式。在Java SE5后,Java提供了Lock接口,相对于Synchronized而言,Lock提供了条件Condition,对线程的等待、唤醒操作更加详细和灵活。下图是Condition与Object的监视器方法....转载 2018-09-19 17:29:55 · 178 阅读 · 0 评论 -
J.U.C之读写锁:ReentrantReadWriteLock
此篇博客所有源码均来自JDK 1.8重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少。然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低。所以就提供了读写锁。读写锁维护着一对锁,一个读锁和一个写锁。通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提...转载 2018-09-19 12:36:15 · 172 阅读 · 0 评论 -
J.U.C之重入锁:ReentrantLock
此篇博客所有源码均来自JDK 1.8ReentrantLock,可重入锁,是一种递归无阻塞的同步机制。它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大、灵活的锁机制,可以减少死锁发生的概率。API介绍如下:一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些......原创 2018-09-18 15:53:59 · 259 阅读 · 0 评论 -
J.U.C之AQS:阻塞和唤醒线程
此篇博客所有源码均来自JDK 1.8在线程获取同步状态时如果获取失败,则加入CLH同步队列,通过通过自旋的方式不断获取同步状态,但是在自旋的过程中则需要判断当前线程是否需要阻塞,其主要方法在acquireQueued():if(shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt()) in...转载 2018-09-18 15:46:37 · 395 阅读 · 0 评论 -
J.U.C之AQS:同步状态的获取与释放
此篇博客所有源码均来自JDK 1.8在前面提到过,AQS是构建Java同步组件的基础,我们期待它能够成为实现大部分同步需求的基础。AQS的设计模式采用的模板方法模式,子类通过继承的方式,实现它的抽象方法来管理同步状态,对于子类而言它并没有太多的活要做,AQS提供了大量的模板方法来实现同步,主要是分为三类:独占式获取和释放同步状态、共享式获取和释放同步状态、查询同步队列中的等待线程情况。自定...转载 2018-09-18 12:20:56 · 188 阅读 · 0 评论 -
J.U.C之AQS:CLH同步队列
此篇博客所有源码均来自JDK 1.8在上篇博客中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列。CLH同步队列是一个FIFO双向队列,AQS依赖它来完成同步状态的管理,当前线程如果获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node)并将其加入到CLH同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获...转载 2018-09-18 09:51:31 · 511 阅读 · 0 评论 -
J.U.C之AQS:AQS简介
Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略(深入分析synchronized的实现原理),但是与Lock相比synchronized还是存在一些缺陷的:虽然synchronized提供了便捷性的隐式获取锁释放锁机制(基于JVM机制),但是它却缺少了获取锁与释放锁的可操作性,可中断、超时获...转载 2018-09-17 17:49:51 · 249 阅读 · 0 评论 -
Java内存模型之从JMM角度分析DCL
DCL,即Double Check Lock,中卫双重检查锁定。其实DCL很多人在单例模式中用过,LZ面试人的时候也要他们写过,但是有很多人都会写错。他们为什么会写错呢?其错误根源在哪里?有什么解决方案?下面就随LZ一起来分析问题分析我们先看单例模式里面的懒汉式:public class Singleton { private static Singleton singlet...转载 2018-09-17 17:05:53 · 234 阅读 · 0 评论 -
[译]Java虚拟机是如何执行线程同步的
想介绍下synchronized的原理,但是又不知道从何下手,在网上看到一篇老外的文章,介绍了和线程同步相关的几个基础知识点。所以想把它翻译一下给大家看看。相信看过这些基础知识之后再看我后面要写的synchronized的原理就会好理解一点了。原文地址:How the Java virtual machine performs thread synchronization了解Java语言的人都知道...转载 2018-07-06 11:57:52 · 375 阅读 · 0 评论 -
不使用synchronized和lock,如何实现一个线程安全的单例?(二)
如果不那么吹毛求疵的话,可以使用枚举、静态内部类以及饿汉模式来实现单例模式。见:不使用synchronized和lock,如何实现一个线程安全的单例?但是,上面这几种方法其实底层也都用到了synchronized,那么有没有什么办法可以不使用synchronized和lock,如何实现一个线程安全的单例?答案是有的,那就是CAS。关于CAS,我博客中专门有一篇文章介绍过他,很多乐观锁都是基于CAS...转载 2018-07-06 11:57:16 · 2734 阅读 · 0 评论 -
乐观锁的一种实现方式——CAS
在深入理解乐观锁与悲观锁一文中我们介绍过锁。本文在这篇文章的基础上,深入分析一下乐观锁的实现机制,介绍什么是CAS、CAS的应用以及CAS存在的问题等。线程安全众所周知,Java是多线程的。但是,Java对多线程的支持其实是一把双刃剑。一旦涉及到多个线程操作共享资源的情况时,处理不好就可能产生线程安全问题。线程安全性可能是非常复杂的,在没有充足的同步的情况下,多个线程中的操作执行顺序是不可预测的。...转载 2018-07-06 11:55:53 · 331 阅读 · 0 评论 -
【深入理解多线程】 Java虚拟机的锁优化技术(五)
前情提要通过前面几篇文章,我们已经知道:1、同步方法通过ACC_SYNCHRONIZED关键字隐式的对方法进行加锁。当线程要执行的方法被标注上ACC_SYNCHRONIZED时,需要先获得锁才能执行该方法。《深入理解多线程(一)——Synchronized的实现原理》2、同步代码块通过monitorenter和monitorexit执行来进行加锁。当线程执行到monitorenter的...原创 2018-04-25 15:15:02 · 590 阅读 · 0 评论 -
【深入理解多线程】 Moniter的实现原理(四)
在深入理解多线程(一)——Synchronized的实现原理中介绍过关于Synchronize的实现原理,无论是同步方法还是同步代码块,无论是ACC_SYNCHRONIZED还是monitorenter、monitorexit都是基于Monitor实现的,那么这篇来介绍下什么是Monitor。操作系统中的管程如果你在大学学习过操作系统,你可能还记得管程(monitors)在操作系统中是很重...转载 2018-04-25 15:02:26 · 1245 阅读 · 0 评论 -
【深入理解多线程】 Java的对象头(三)
上一篇文章中我们从HotSpot的源码入手,介绍了Java的对象模型。这一篇文章在上一篇文章的基础上再来介绍一下Java的对象头。主要介绍一下对象头的作用,结构以及他和锁的关系。Java对象模型回顾与勘误在上一篇文章中,关于对象头的部分描述有误,我已经在我博客的文章中就行修正 。这里再重新表述一下。每一个Java类,在被JVM加载的时候,JVM会给这个类创建一个instanceKlas...转载 2018-04-25 14:55:45 · 3775 阅读 · 0 评论 -
【深入理解多线程】 Java的对象模型(二)
上一篇文章中简单介绍过synchronized关键字的方式,其中,同步代码块使用monitorenter和monitorexit两个指令实现,同步方法使用ACC_SYNCHRONIZED标记符实现。后面几篇文章会从JVM源码的角度更加深入,层层剥开synchronized的面纱。 在进入正题之前,肯定有些基础知识需要铺垫,那么先来看一下一个容易被忽略的但是又很重要的知识点 —— Java对...转载 2018-04-25 14:50:14 · 711 阅读 · 0 评论 -
【深入理解多线程】Synchronized的实现原理(一)
synchronized,是Java中用于解决并发情况下数据同步访问的一个很重要的关键字。当我们想要保证一个共享资源在同一时间只会被一个线程访问到时,我们可以在代码中使用synchronized关键字对类或者对象加锁。那么,本文来介绍一下synchronized关键字的实现原理是什么。在阅读本文之间,建议先看下Java虚拟机是如何执行线程同步的 。反编译众所周知,在Java中,synchr...转载 2018-04-25 12:26:22 · 700 阅读 · 0 评论