
Java并发
Java并发的一些笔记
源大郎
这个作者很懒,什么都没留下…
展开
-
《深入理解JVM》第13章现场安全与锁优化
线程安全当多个线程访问一个对象时,如果可以不考虑线程的调度以及交替执行,也不需要额外的同步手段,或者调用方进行任何其他操作,所得到的结果都是正确,那么就被称为线程安全。如果一个时间段只有一个线程在操作(写操作之类)该对象,那必然也是线程安全的。或者说不影响对象状态的多线程一起操作。(就有点像买东西,大家都能看,但是如果要拆开包装对它进行一些会影响到商品的一些性质之类的,只能“买”下来了)。Java中的线程安全线程安全可以当成一个强弱程度的概念而不用简单当成是或否的概念。不可变不可变基本类型一定原创 2020-05-30 06:19:32 · 176 阅读 · 0 评论 -
《深入理解JVM》第12章Java内存模型与线程【1】线程部分
Java与线程从JVM的角度讲线程线程的实现线程是比进程更轻量级的调度执行单位,它将进程的资源分配与执行调度分开使得各个线程既可以共享进程资源,又可以独立调度,它是目前Java中进行处理器资源调度的基本单位。主要有三种实现方式:1.内核线程实现(1:1实现)2.使用用户线程实现(1:N实现)3.使用用户线程加轻量级进程混合实现(N:M实现)内核线程(1:1)实现(主流JVM采用这种)内核线程是直接由操作系统内核支持的线程 ,由内核来完成线程切换,内核通过操纵调度器对线程进行调度,并负责将任原创 2020-05-28 03:26:19 · 174 阅读 · 0 评论 -
《深入理解JVM》第12章Java内存模型与线程【0】(JMM部分)
概述由于计算机计算能力与它的存储和通信子系统的速度差距过大,所以必须使用一些手段来压榨处理器的运算能力,这个手段之一就是多线程并发。硬件的效率与一致性由于计算速度与IO操作的速度差异了几个数量级,所以不得不为现代计算机系统加入一层或者多层读写速度尽可能接近处理器运算速度的高速缓存。但是由于处理器都共享同一块主存但是彼此之间的高速缓冲是不可见的,这就引发了缓存一致性(可见性)问题。而且为了处理器内部的运算单元可以被充分利用到,处理器可能回对输入代码进行乱序执行来优化(重排序),这就引发了有序性问题。原创 2020-05-27 06:30:34 · 188 阅读 · 0 评论 -
《Java并发编程的艺术》十一章Java并发编程实践
啊最后一章了!这本书真的是一本很棒的书,除了到了后面章节内容有点老了(JDK6或者7吧?),得自己翻源码以外,其他我基本上挑不出毛病,噢还有就是有些地方写得有点泛(我指JUC那块),或许作者觉得这些自己多用,多看看源码也能明白吧。总之是一本很好的书。生产者和消费者模式并发编程中使用生产者/消费者模式能够解决绝大多数并发问题。该模式用过平衡生产线程和消费线程的工作能力来提升程序整体处理数据的速度。生产者和消费者模式往往通过一个容器来充当第三者来解耦生产者和消费者,它们之间并不直接通信。生产者产生任务放原创 2020-05-26 04:43:35 · 163 阅读 · 0 评论 -
多线程题目——打印零与奇偶数
好像LC上大部分(就那几道)多线程题目都是考察等待通知机制。这题要求0奇0偶的顺序打印直至n.那就得构造屏障嘛,保证它们能够交替允许,信号量Semaphore就能很好的完成这个工作。设一个变量为公共变量,记录当前应该打印的奇偶数,在0方法里递增。别忘了再最后唤醒它们去结束等待。代码如下:class ZeroEvenOdd { private int n; Semaphore zero = new Semaphore(1); Semaphore even = new Sem.原创 2020-05-25 21:11:50 · 450 阅读 · 0 评论 -
《Java并发编程的艺术》Executor框架
上一章学了线程池,这个框架为我们提供了一些线程池。Executor框架简介二级调度模型程序通过Executor框架控制上层的调度,下层的调度由操作系统内核控制。所谓上层就是线程池中哪些任务在等待池,哪些任务被分配到运行线程上之类的。所谓下层就是哪些线程被分配到哪些CPU上去执行。Executor框架的结构与成员1.结构主要分为三个部分任务异步计算的结果线程池使用示意图2.成员(1)ThreadPoolExecutor它通常由工厂类Executors创建。主要有三种线程原创 2020-05-23 07:10:01 · 172 阅读 · 0 评论 -
《Java并发编程的艺术》第九章Java中的线程池
使用线程池的好处:降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁的开销提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。提高线程的可管理性:使用线程池可以统一分配,调优以及监控,提高稳定度。线程池的实现整个线程池的主要流程如下所示。以ThreadPoolExecutor执行execute方法为例,具体的流程就是如果当前运行的线程少于corePoolSize(自行设定,最大值(1 << Integer.SIZE - 3) - 1),下面maximu原创 2020-05-21 07:05:22 · 235 阅读 · 0 评论 -
《Java并发编程的艺术》第七、八章Java中的13个原子操作类以及常用并发工具笔记
我觉得我不能看一个写一个源码分析了,太费时了。还是先按着书中思路适当捋一下就行了。原子操作类顾名思义就是能够保持一些本身为复合操作的原子性(比如自增啊之类的),可以理解为一些复合动作的加锁(虽然不太恰当,有点本末倒置的味道,用锁不是目的,保持原子性才是,而用锁只是一种手段。),不过是是以CAS的方式。像volatile就是对读写分别加“锁”(内存屏障)的感觉,而原子类就是将一些设置好的操作加"锁",而使用锁就是对某个代码段(方法不严格的说也是个代码段啦),加锁。基本类型这些类基本上看名就能够知道是什么原创 2020-05-19 04:44:10 · 144 阅读 · 0 评论 -
《Java并发编程的艺术》第六章Java并发容器和框架(1)ConcurrentHashMap(基于JDK11)
这一章讲得有点泛(不过讲详细了估计就得写四章不止了2333),用的JDK版本也与我的不一样(我的是11)…emmm按着书的思路,本地的JDK源码梳理吧。ConcurrentHashMapConcurrentHashMap简单的说就是并发下使用的HashMap。为啥不直接用HashMap呢?一方面是值会丢失(这个倒是好理解,阔能出现覆盖的情况,如果俩线程盯着的是同一个地方的话,就会出现这个问题,而且如果是红黑树可能出现,虽然存了看着没丢失,但是如果再转换回链表估计还会丢几个)。另一方面就是会引发死循原创 2020-05-17 19:20:25 · 431 阅读 · 0 评论 -
LeetCode多线程题目——交替打印FooBar(用等待通知机制构造屏障)
想要交替输出,两边线程就需要通信,因为只有两个线程分别调用两个方法,所以仅需要使用一个布尔类型的量作为信号即可,用flag的两种状态来分别限制两者,如果为真,foo线程等待 ,bra执行,执行完毕唤醒foo如果为假,bar线程等待,foo执行,执行完毕唤醒bar以下分别ReentrantLock和synchronized代码块来实现。class FooBar { private int n; private ReentrantLock lock = new ReentrantLock.原创 2020-05-10 17:34:26 · 266 阅读 · 0 评论 -
《Java并发编程的艺术》第五章Java中的锁(2)(等待队列,重入锁,(非)公平锁与读写锁)
等待队列(Condition)Condition与获取Obejct锁的监视器方法类似。有的区别就是:ObejctCondition等待队列的个数1多个在等待状态不响应中断不支持支持当前线程释放锁并进入等待状态到将来某个时间不支持支持Condition与Obejct监视器的等待队列是一样的,绑定于所依赖的锁,所以也需要先获取锁才能进入等待队列。与同步器的关系大概如图所示。等待队列中的节点是一个包含的内容于同步队列是一样的,他们本质是一种节点。不过等原创 2020-05-09 22:15:07 · 247 阅读 · 0 评论 -
哲学家进餐(避免死锁)
这题的考察点是避免死锁(一个叉子就是一把锁),假设不加限制让线程自由的获取锁,那么大家都先拿位于自己左侧的叉子再拿右侧的叉子,由于是个圆桌,相邻的俩人前一个人左侧就是下一个人的右侧(逆时针方向),如果大家都拿了左侧的叉子那完犊子,都饿死吧。要解决死锁首先先明确下死锁造成的原因有兴趣阔以看看这篇生活中的死锁1.互斥条件: 资源不能被共享。(互相喂?这也太哲学了吧)2.请求与保持条件: 已经得到资源的进程可以再次申请新的资源。(其实我觉得单个叉子吃也不是不可以,哲学家就是麻烦)3.非剥夺条件: 已..原创 2020-05-09 17:06:01 · 835 阅读 · 0 评论 -
详解一道多线程笔试题(考察wait())
原题大概是这么个意思。一个线程A 执行setJob方法(设为方法1),一个线程B执行getJob方法(设为方法2),问下面这段代码有啥问题。 Object lock = new Object(); Object job; public void setJob(Object job){ this.job = job; synchronized (lock){ lock.notifyAll();原创 2020-05-09 06:11:16 · 330 阅读 · 1 评论 -
《Java并发编程的艺术》第五章Java中的锁(1)(AQS中的独占锁与共享锁)
真就是套娃结构23333一般自行实现一个同步组件需要实现Lock接口,而实现Lock接口又必须得需要一个队列同步器(AQS),一般用静态内部类的方式实现它,而ASQ内部又有个等待队列(ConditionObject).为啥这样搞?答案也很明显,前面讲 synchronized 说过,要获取一个锁,本质是获取它的监视器(monitor),如果没有成功获取,则进入该对象的同步队列,然后状态变为阻塞...原创 2020-05-08 03:47:04 · 434 阅读 · 4 评论 -
《Java并发编程基础》第四章Java并发编程基础笔记
1.什么是线程这个问题,大厂大概率都会问到(线程和进程的区别)。现代操作系统再运行一个程序时都会为其创建一个进程,它是操作系统资源分配最小的单位,而进程可创建多个线程,线程是现代操作系统调度的最小单位。详细见此文Java程序是个天生的多线程。可由下面程序打印线程信息。public class MultiThread { public static void main(String...原创 2020-05-03 03:33:10 · 157 阅读 · 0 评论 -
《Java并发编程的艺术》第三章从双重检测机制(延迟初始化)到volatile等三个同步原语的内存语义
延迟初始化有时候一些高开销的对象,需要在使用时再初始化,以减轻初始化时的消耗,这时就需要延迟初始化,常见的就是单例模式的懒汉模式。懒汉模式也算是面试常考问题吧,写法如下:public class SingleLazy { public static SingleLazy instance; private SingleLazy(){} public static S...原创 2020-04-24 16:37:29 · 232 阅读 · 0 评论 -
《Java并发编程的艺术》第三章内存模型(基本概念)
并发的两个关键问题通信:线程之间传递信息同步:控制不同线程之间操作发生相对顺序的机制(前因不得先于后果发生)Java采用共享内存模型,通信通过对一个堆上共享变量的读写来进行隐式通信,必须显式的指定某个方法或者某段代码需要线程之间互斥执行。JMM抽象结构在JMM中每个线程中存在一个本地内存的抽象概念(不存在,涵盖了缓存,写缓冲区等),对共享变量的读写会缓存到本地内存,这时其他线程是不可...原创 2020-04-22 18:52:23 · 214 阅读 · 0 评论 -
《Java并发编程艺术》第二章Java并发机制的底层实现
第一章Java并发挑战主要有:上下文切换问题:解决思路:1.减少线程数量2.增长线程内的有效利用率(就是线程运行时间和上下文切换时间)死锁解决思路:1.避免一个线程同时获得多个锁2.避免一个线程在锁内同时占用多个资源。3.尝试使用定时锁(lock.tryLock(timeout))4.对数据库锁,保证操作由一个连接完成资源限制第二章:volatile定义...原创 2020-04-16 17:08:52 · 327 阅读 · 0 评论 -
《Java并发编程实战》3.0设计线程安全的类(不变性后验先验条件),实例封闭
设计线程安全的类在设计线程安全类的过程中,需要包含以下三个基本要素:找出对象状态的所有变量找出约束状态变量的不变性条件建立对象状态的并发访问管理策略找出同步需求(不变性与后验条件)如果一个类中含有不可变对象属性,则应该保证其不变性条件在并发访问情况下被满足;另外如果有需要更新的对象属性,则需要保证其后验条件在状态以及状态转换上施加约束。比如一数字做递增操作,如这次值为22,下一次...原创 2020-04-04 03:41:33 · 443 阅读 · 0 评论 -
《Java并发编程实战》2.1笔记发布与逸出、线程封闭、不变性
发布与逸出发布一个对象的意思是使对象能够在当前作用域外的代码中使用。当某个不应该被发布的对象被发布了则成为逸出(比如再对象构造之前就发布该对象)。注意发布一个对象,它的非私有的属性也同样会被发布。比如一种通过内部类发布对象,这时就会将本类的this引用发布出去(内部类能够调用外部类的属性),所以不要在构造函数中发布某内部对象,这时可能外部对象尚未构造完全。比如下面的代码就会与预期的不一样...原创 2020-04-01 02:44:37 · 183 阅读 · 0 评论 -
《并发编程实战》2.0第三章笔记volatile关键字
可见性重排序与失效数据由于多线程的情况下,某些线程有时候会将一些值缓存起来,读这些缓存而不从主内存中读取所以可能会有问题,它一直在读取一个已经失效的数值这就会导致一些问题(比如下面代码的死循环,还有比如没有线程安全get、set方法阔能读取到更新的值也阔能没读取到,那就很难顶了)。而且一些指令可能会重排序,让结果不像我们预期的那样。尝试下面这个程序大概率会发现,陷入死循环。public c...原创 2020-03-30 02:16:58 · 91 阅读 · 0 评论 -
《并发实战》笔记1.0.第二章安全性,原子性,加锁机制
文章目录《并发实战》1.0.安全性,原子性安全性原子性加锁机制内置锁重入性能、锁状态《并发实战》1.0.安全性,原子性俺开始学并发了!安全性一言以蔽之就是,做正确的事,但是由于并发的场景下,执行顺序不确定所以就容易出现问题。当然如果没有状态性,那咋整都莫得问题,不过如果有,而且需要修改状态,那这个问题就要格外重视。如果有需要重视安全性的问题,那么我们就需要实现它的同步。** 同步机制:...原创 2020-03-29 00:19:32 · 158 阅读 · 0 评论