![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
并发
了不起的盖茨比。
如果把一切都准备好了再前行,那我们永远迈不出第一步。
展开
-
并发的设计模式(三)
1.写在前面前面的几篇博客介绍了几种的并发的设计模式,接下来笔者介绍其他的几种并发的设计模式2.Worker Thread模式:如何避免重复创建线程?2.1Worker Thread 模式及其实现现实中的场景:车间里的工人,有活儿了,大家一起干,没活儿了就聊聊天等着。Worke Thread 对应现实世界里,其实指的就是车间里的工人。不过这里需要注意的是,车间里的工人的数量往往是确定的通过上面的图,你很容易就能想到用阻塞队列做任务池,然后创建固定数量的线程消费阻塞队列中的任务。其实你仔细想会发原创 2020-11-17 16:13:52 · 296 阅读 · 0 评论 -
并发的设计模式(二)
1.写在前面笔者前面已经介绍了几种并发的设计模式,这篇笔者继续讲剩下的几种设计模式2.Guarded Suspension模式2.1概述举个例子:比如,项目组团建要外出聚餐,我们提前预订了一个包间,然后兴冲冲地奔过去,到那儿后大堂经理看了一眼包间,发现服务员正在收拾,就会告诉我们:“您预订的包间服务员正在收拾,请您稍等片刻。”过了一会,大堂经理发现包间已经收拾完了,于是马上带我们去包间就餐。Guarded Suspension模式直译过来就是保护性地暂停,下图就是 Guarded Suspensi原创 2020-11-17 14:05:42 · 182 阅读 · 0 评论 -
并发的设计模式(一)
1.写在前面笔者介绍并发的工具类,以及基础的东西,今天笔者打算来介绍一下并发中的设计模式。2.不变性模式2.1概述不变性模式,所谓不变性,简单来讲,就是对象一旦被创建之后,状态就不再发生变化。换句话说,就是变量一旦被赋值,就不允许修改了(没有写操作);没有修改操作,也就是保持了不变性。2.2快速实现具备不可变性的类就是将一个类所有的属性都设置成final的,并且只允许存在只读的方法,那么这个类基本上就具备不可变性了。更严格的做法是这个类本身也是final的,也就是不允许继承。java中一些常用原创 2020-11-16 16:39:36 · 314 阅读 · 0 评论 -
并发工具类(四)
1.写在前面前面的几篇博客介绍了并发工具类的其中的一部分,今天是最后并发工具类是最后一篇博客,后面的博客会介绍并发的模式。好了,废话不多说,直接上内容吧。2.CompletableFuture:异步编程异步化的编程,利用多线程优化性能这个核心方案得以实施的基础。2.1CompletableFuture 的核心优势我们再来看下上篇博客中讲的烧茶泡水的例子,具体的分工图如下:实现的代码如下:// 任务 1:洗水壶 -> 烧开水CompletableFuture<Void> f原创 2020-11-02 14:33:36 · 303 阅读 · 0 评论 -
并发工具类(三)
1.写在前面之前的博客已经介绍了一部分的JUC包下的一些并发的工具类,还有一部分的并发的工具类没有介绍,笔者今天继续介绍剩下的并发的工具类。2.原子类2.1累加前面笔者写了一个累加器的案例,具体的代码如下。这个例子中add10k这个方法不是线程安全的,问题就出在变量count的可见性和count+1的原子性上。可见性问题可以用volatile来解决,而原子性问题我们前面一直都是采用互斥锁方案public class Test { long count = 0; void add10K() {原创 2020-10-13 16:05:18 · 134 阅读 · 0 评论 -
并发工具类(二)
1.写在前面一个长假终于过完了,休息了8天,什么事也没有做,突然想想我是一个不称职的笔者,这个长假竟然一篇博客没有写。体重也重了不少,感觉整个人都是灰暗。好好调整状态,继续起航。上篇博客大概讲了下并发工具类的一部分。今天我们来讲下剩下的部分。2.StampedLock2.1StampedLock支持的三种锁模式ReadWriteLock支持两种模式:一种是读锁,一种是写锁StampedLock支持三种模式:写锁、悲观读锁、乐观锁。其中,写锁、悲观读锁的语义和ReadWriteLock的写锁、读锁的原创 2020-10-09 14:11:58 · 150 阅读 · 0 评论 -
并发工具类(一)
1.写在前面前面的博客,笔者大概介绍了下并发的一些的基础的知识。同时也讲了下并发中很重要的一个知识,就是管程,什么是管程?就是管理共享变量以及对共享变量的操作的过程,让他们支持并发。今天我们就来介绍下java提供的一些并发工具类,以及管程在并发工具类中的使用。2.Lock并发中一直有两大核心的问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。Lock用于解决互斥的问题,Condition用于解决同步问题。2.1再造管程的理由前面我们介绍的一个死锁的问题原创 2020-09-29 13:02:41 · 331 阅读 · 0 评论 -
从并发的源头谈起
1.写在前面不管什么语言,并发的编程都是在高级的部分,可见并发有多难,因为并发的涉及的知识太广,不单单是操作系统的知识,还有计算机的组成的知识等等。说到底,这些年硬件的不断的发展,但是一直有一个核心的矛盾在:CPU、内存、I/O设备的三者的速度的差异。这就是所有的并发的源头2.解决办法CPU增加了缓存,以均衡与内存的差异;操作系统增加了进程、线程,以分时复用CPU,进而均衡CPU与I/O设备的速度差异;编译程序优化指令执行次序,使得缓存能够得到更加合理的利用。以上的解决办法都会导致相应的问题原创 2020-09-21 16:51:19 · 164 阅读 · 0 评论 -
Java线程与管程技术
1.写在前面并发编程不单单在java语言中有应用到,在其他的语言上也有用到。并发编程这个技术领域已经发展了很久了。其中技术和理论也是很多同样也是复杂的。那么有没有一种技术可以很方便地解决我们的并发问题呢?那就是管程技术。本篇博客主要介绍管程技术。然后就是Java的线程一些技术,最后再介绍一下如何用面向对象思想写好并发程序。2.什么是管程Java采用的是管程技术,synchronized关键字及wait()、notify()、notifyAll()这三个方法都是管程的组成部分。而管程和信号量是等价的。所原创 2020-09-21 16:28:35 · 627 阅读 · 1 评论 -
AQS之await和signal源码解析
上篇的文章中我们介绍了AQS源码中lock方法和unlock方法,这两个方法主要是用来解决并发中互斥的问题,这篇文章我们主要介绍AQS中用来解决线程同步问题的await方法、signal方法和signalAll方法,这几个方法主要对应的是synchronized中的wait方法、notify方法和notifAll方法。在介绍着这几个方法之前,我们先来看看这个几个方法是怎么使用的。我们实现一个阻塞的队列。import java.util.ArrayList;import java.util.Arra原创 2020-07-06 14:58:10 · 566 阅读 · 0 评论 -
从源码的角度深入理解AQS加锁解锁过程
提起AQS(AbstractQueuedSynchronizer),不得不让我们想起多线程的同步的几种的实现方式,主要是wait/notify,synchronized,ReentrantLock,下面我们会介绍几种同步的实现方式,从而推理出AQS的加锁的过程。自旋的方式import java.util.concurrent.atomic.AtomicInteger;public class SpinLocksDemo { //标识--是否有线程在同步块---是否有线程上锁成功原创 2020-06-30 13:25:12 · 947 阅读 · 7 评论 -
并发编程(三)线程池的使用
上节部分并发编程(二)Executor的使用import java.util.concurrent.Executor;public class Demo1_Executor implements Executor { public static void main(String[] args) { Demo1_Executor demo1_executor = new Demo1_Executor(); demo1_executor.execute(()原创 2020-06-25 11:08:04 · 170 阅读 · 0 评论 -
深入理解synchronized关键字
上一篇博客中我们通过JOL工具查看了加锁对象的对象头,也大致的了解了偏向锁、轻量锁、重量锁的对象头,但是什么时候是偏向锁?什么时候又是轻量锁?什么时候又是重量锁?为了说明这个问题,我们假设我们运行的程序中有一个线程A,有一个线程B,还有一个加锁对象MyLock。偏向锁:当线程A对锁对象MyLock加锁的时候,没有其他的线程,首次加锁的时候就是偏向锁轻量锁:当线程A对锁对象MyLock加锁的时候,然后线程A结束的时候,这时候B线程对锁对象MyLock加锁,这个时候就是轻量锁。可能有人会认为这个时候原创 2020-06-20 20:13:57 · 237 阅读 · 0 评论 -
深入理解Java的对象头mark word
上一篇博客我们编译了Linux源码来证明了Java中有偏向锁,但是我们从周志明大佬的《深入理解java虚拟机》的书中知道,我们可以通过分析Java对象头中MarkWord来查看是那种锁,下面是32位JVM的对象中的Mark Word图,但是随着JDK的不断升级,JDK没有32位的版本,所以我们要研究64的JVM中对象的MarkWord。当我在网上找了很多资料的后,发现都是32位JVM,无法满足我们对64位JVM的研究,于是我想到了JDK源码,看看其中有没有注释,于是我去编译好的JDK源码找找看,找到对应原创 2020-06-19 12:49:55 · 11687 阅读 · 12 评论 -
并发编程(二)进阶部分
上节并发编程(一)synchronized静态方法锁定的是类对象import java.util.concurrent.TimeUnit;public class Demo { public synchronized static void test1() { System.out.println("test1 start"); try { TimeUnit.SECONDS.sleep(3); } catch (I原创 2020-06-17 22:04:39 · 186 阅读 · 0 评论 -
并发编程(一)基础部分
最近一直在搞并发,但是都是偏于理论和证明的方面,代码写的少之又少,今天主要讲一些并发的代码书写。具体会从通过多个Demo来加深你对并发的理解。synchronized关键字/** synchronized关键字* synchronized关键字锁定的是对象不是代码块,demo中锁的是object对象的实例* 锁定的对象有两种:1.类的实例,2.类对象(类锁)* 加synchronized关键字之后不一定能实现线程安全,具体还要看锁定的对象是否唯一* */public class Demo原创 2020-06-17 15:42:22 · 262 阅读 · 0 评论 -
通过修改Linux源码证明有偏向锁的存在
通过上篇博客《基于JNI手动模拟Java线程》,我们知道Java线程的创建方式,本质:就是调用操作系统底层的线程创建函数,Linux中是pthread_create函数那么线程加锁在操作系统又是调用什么函数呢?查了一下是调用操作系统中的pthread_mutex_lock函数。回到我们今天的主题:证明JDK1.6以后,JDK对synchronized关键字进行了优化,引入的偏向锁(当线程没有竞争的时候,偏向锁只会加锁一次,后面再去调用该方法的时候,不会再去操作系统调用对应的操作的系统的加锁的函数),JDK1原创 2020-06-12 20:37:09 · 798 阅读 · 2 评论 -
基于JNI手动模拟Java线程
并发一直是个难点,也是面试的重灾区,闲来无事,就想知道Java的线程如何启动起来的。我们都知道Java的线程和系统的线程是一一对应的。要想知道Java的线程是如何启动起来,我们要先知道Java的线程的创建的方式。Java线程的创建方式。继承Thread类实现Runnable接口我们都知道Java线程创建方式有上面两种方式,但是还是没有谈论到我们的重点,Java的线程是如何启动起来,于是我要去查看start方法的源码。当我们点开源码发现start()方法中调用了start0()方法,而start原创 2020-06-11 10:45:07 · 563 阅读 · 1 评论 -
Ubuntu18.04下编译JDK12
由于最近一直在研究并发,所以难免会搞到Java的底层源码,所以编译JDK的源码是非常有必要的,笔者编译JDK源码的环境如下:系统:Ubuntu18.04.4JDK源码:JDK12请尽量和笔者的编译环境一致。下载JDK12的源码方式一:Linux下面直接执行如下的命令hg clone https://hg.openjdk.java.net/jdk/jdk12[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C4pXbBzE-1591778715020)(C原创 2020-06-10 17:03:44 · 1060 阅读 · 1 评论