![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
线程
文章平均质量分 74
前进人生
希望能和大家一起交流进步
展开
-
线程学习(33)-Semaphore,CountDown,以及CyclicBarrier
无用原创 2022-06-22 11:38:02 · 91 阅读 · 0 评论 -
线程学习(32)-AQS
AQS,全称是AbstractQueuedSynchronizer,是阻塞锁和相关的同步器的框架。AQS内部核心。1.state,用过state属性来表示资源的状态,分为独占锁与共享锁,子类会根据这个状态来维护获取锁和释放锁的方式,来决定锁的类型。getState(),获取当前状态setState(),给当前状态赋值compareAndSetState,使用CAS的方式给State来进行赋值。就像AQS的内部的acquire以及relaese等系列方法,都是针对于AQS的状态来进行更改。2.Node阻塞队列原创 2022-06-20 17:12:57 · 123 阅读 · 0 评论 -
线程学习(31)-异步模式之工作线程
让有限的工作线程(Worker Thread)来轮流异步处理无限多的任务。也可以将其归类为分工模式,它的典型实现就是线程池,也体现了经典设计模式中的享元模式。不过利用线程池处理任务时,需要注意一下,就我这里写了个生产者消费者,因为在生产者,消费者中,如果消费速度跟不上生产速度,那么很可能生产者将线程池中的所有资源都占有,并且wait等待,就没有办法继续进行工作了。 创建多少线程池合适CPU密集型运算通常采用 cpu 核数 + 1 能够实现最优的 CPU 利用率,+1 是保证当线程由于页缺失故原创 2022-06-19 12:52:32 · 144 阅读 · 0 评论 -
线程学习(30)-线程池
ThreadPoolExecutor内部由一个32位的字段ctl来标识线程池的状态。其中前三位代表线程池的状态,后29位代表了线程池的数量。线程池的状态共划分为RUNNING(111),SHUTDOWN(000),STOP(001),TIDYING(010),TERMINATED(011)。默认情况下,TERMINATED>TUDYING>STOP>SHUTDOWN>RUNNING状态。第一位其实是正负号。RUNNING代表了线程池正在运行。SHUTDOWN代表了线程池不会接收新任务,但会将阻塞队列中的任务原创 2022-06-18 21:27:27 · 283 阅读 · 0 评论 -
线程学习(29)-自定义线程池
听了老师讲了一次,自己又敲了一次,线程池这块自定义一个简单的是可以勉强做到了。自定义线程池在老师的讲解下,其实共划分了三项,分别为阻塞队列,worker线程派生,以及线程持类。阻塞队列是一个生产者消费者模式的应用方式,因为它的目的就是为了在核心线程满了时,将内容存放至阻塞队列中(生产者),在阻塞队列满了时,会wait阻塞等待,然后等核心线程的内容执行完成后。阻塞队列的内容被消费。worker线程,其实就是继承了Thread类,只不过在run方法中,会对任务进行监听,会采用一个for循环,如果当前持有的任务执原创 2022-06-17 12:39:13 · 133 阅读 · 0 评论 -
线程学习(28)-连接池
分析一下,最简单的连接池要有什么?属性的话需要有连接数,以及连接数组,以及连接状态(代表当前连接是否被用)。以及一个全局状态(保证线程安全)。方法的话,获取连接(多线程),以及释放连接(单线程)。以及相关的构造函数。...原创 2022-06-16 15:42:54 · 201 阅读 · 0 评论 -
线程学习(27)-不可变类
什么是不可变类?不可变类为什么是线程安全的?如果一个对象在不能修改其内部状态时,就代表了当前类不会存在对内部属性进行写的情况,也就是说它是线程安全的。因为我们平时接触的线程不安全,都是在多个线程进行操作时,并发对内部元素进行修改,发生了指令交错,最后这个内部元素被修改的出现了问题。而不可变类,之所以不可变,是因为内部元素或者类,或者方法都设置为final类型,就拿属性举例,final修饰了,基础类型就不可能发生并发修改的情况。而引用类型,虽然可能会改变final所修饰对象的成员变量。但是在不可变类中,原创 2022-06-16 15:25:08 · 252 阅读 · 0 评论 -
线程学习(26)-Atomic原子类型系列
因为在之前的学习中,也学到了多个线程安全的方法组合到一块却不是线程安全的。如果采用synchronized这种方式,锁比较重。所以提供一系列的基于CAS的组合方法类的API,来用以保证线程安全。在jdk1.8的文档里,这三种类型的方法基本上都是类似的。源码的底层都是do{}While()循环调用CAS方法完成操作。AtomicReference底层是一个泛型结构,底层使用==来保证compareAndSet中的compare,所以可以搭配一些不可变类来进行使用。比如String,BigInteger,原创 2022-06-16 14:54:52 · 688 阅读 · 0 评论 -
线程学习(25)-乐观锁方式CAS简介
原先所学的加锁,例如synchronized,ReetrantLock这些加锁方式都是悲观锁,即当前线程对加锁的内容进行操作时,其它的线程只能等待该线程锁住的内容执行完成之后,才可以获得锁,最终执行自己的业务。而今天所学的cas,是一种乐观锁的机制。cas,全拼是compare and set,即先比较后赋值(cas是个原子操作)。即当线程修改共享变量的时候,并不会像悲观锁一样,控制着不让其它线程修改当前变量,可以这么理解:1.线程A先获取到了主存值1,拷贝至工作内存2.线程B获取到主存值1,拷贝至工作内存原创 2022-06-12 18:20:40 · 1081 阅读 · 3 评论 -
线程学习(23)-happen-before原则
happens-before 规定了对共享变量的写操作对其它线程的读操作可见,它是可见性与有序性的一套规则总结,抛开以下 happens-before 规则,JMM 并不能保证一个线程对共享变量的写,对于其它线程对该共享变量的读可见。(可以理解为先于什么发生)线程解锁 m 之前对变量的写,对于接下来对 m 加锁的其它线程对该变量的读可见 线程对 volatile 变量的写,对接下来其它线程对该变量的读可见 线程 start 前对变量的写,对该线程开始后对该变量的读可见 线程结束前对变量的写,对其它线程原创 2022-06-11 15:32:05 · 65 阅读 · 0 评论 -
线程学习(22)-dcl(double-checked locking)
double-checked locking,即dcl,代表多重校验锁。一听这个名字,就会想到双重校验锁单例模式,以及前面所说的犹豫模式。下面先写个正确的单例。上面的代码是一个完整的双重校验锁。第一个if防止每次试图创建对象时,都需要进入synchronized中进行判断。第二个if防止多线程剑发生指令交错,最终导致创建出多个对象。volatile代表了防止创建对象时发生指令重排,最终出现问题。原因写在注释上了。这里主要就着volatile来分析一下。javap反编译的指令集 17代表创建对象,对象引原创 2022-06-11 11:44:50 · 168 阅读 · 0 评论 -
线程学习(21)-volatile有序性
volatile保证了有序性。这里的有序性,不是前面所说的指令交错的问题,而是指令中更底层的东西。JVM在不影响正确性的情况下,会对语句的执行顺序来进行重排。为了提高指令执行的效率。Clock Cycle Time主频的概念大家接触的比较多,而 CPU 的 Clock Cycle Time(时钟周期时间),等于主频的倒数,意思是 CPU 能够识别的最小时间单位,比如说 4G 主频的 CPU 的 Clock Cycle Time 就是 0.25 ns,作为对比,我们墙上挂钟的Cycle Time 是 1s原创 2022-06-11 10:42:04 · 713 阅读 · 1 评论 -
线程学习(21)-volatile可见性
线程的三大特性主要划分为原子性,可见性,有序性。在原先的synchronized学习中,涉及到的大多是原子性,现在记录下可见性。JMM,即Java Memory Model,java内存模型,定义了主存,工作内存等一系列抽象概念,底层对应着CPU寄存器,缓存,硬件内存,CPU指令优化等。现在从抽象概念来进行理解,主存,还有工作内存,最终理解可见性。结果是这样的。 很明显没有执行完成。把volatile的注释解开,注释掉原有定义,结果是这样的。造成这种现象的原因是什么,从主存,工作内存的角度来进行理解。原创 2022-06-10 17:01:44 · 556 阅读 · 0 评论 -
线程学习(20)-使用多线程间隔打印字符串
假设我现在有三个字符串,abcdefg,1234567,!@#$%^&,我期望使用多线程来进行打印,打印的结果为a1!b2@c3#d4$e5%f6^g7&。这也是道面试题。有三种方案,synchronized,ReentrantLock结合Condition,LockSupport的park,unpark方法三种。这个题的思路是要做什么,使用多线程,并且控制执行线程的执行顺序,来完成对结果的打印。控制线程执行顺序,肯定要用到线程的通信机制。synhronized中配合锁对象中的wait()以及notify,原创 2022-06-01 00:48:36 · 285 阅读 · 0 评论 -
线程学习(19)-ReentrantLock基础
终于写到这了,记录下ReentrantLock的特性。ReetentLock与Synchronized的特点比较:ReetentLock支持zhon原创 2022-05-31 19:02:24 · 1277 阅读 · 0 评论 -
【无标题】线程学习(18)-多把锁下的线程问题,死锁,活锁,饥饿
多把锁的应用减小锁粒度,提交并发度。package com.bo.threadstudy.four;import lombok.extern.slf4j.Slf4j;/** * 多把锁的情况,以及后期的死锁,活锁,饥饿现象,哲学家就餐 */@Slf4jpublic class ManyLockTest { private static final Object lock1 = new Object(); private static final Object l原创 2022-05-30 18:25:14 · 135 阅读 · 0 评论 -
线程学习(17)park,unpark
个人笔记,勿喷原创 2022-05-30 11:08:46 · 3072 阅读 · 0 评论 -
线程学习(16)-生产者消费者
定义与前面的保护性暂停中的 GuardObject 不同,不需要产生结果和消费结果的线程一一对应消费队列可以用来平衡生产和消费的线程资源生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据消息队列是有容量限制的,满时不会再加入数据,空时不会再消耗数据JDK 中各种阻塞队列,采用的就是这种模式有点类似MQ的模式,这个直接写代码吧。重复消费等乱七八糟的现象就不考虑了。package com.bo.threadstudy.four;import lombo...原创 2022-05-30 00:45:35 · 83 阅读 · 0 评论 -
线程学习(15)-保护性暂停模式
保护性暂停是什么?定义即 Guarded Suspension,用在一个线程等待另一个线程的执行结果要点有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject如果有结果不断从一个线程到另一个线程那么可以使用消息队列(见生产者/消费者)JDK 中,join 的实现、Future 的实现,采用的就是此模式因为要等待另一方的结果,因此归类到同步模式普通方式package com.bo.threadstudy.four;import lom.原创 2022-05-29 22:59:35 · 136 阅读 · 0 评论 -
线程学习(14)-wait notify notifyAll
简介wait ,notify,notifyAll和原先学习的方法不同,这些是Object类中的方法,为什么是Object类中的方法,而不定义成线程中的方法。当时面试的时候,面试官问了个这问题。网上找一下标准答案。wait与notify,notifyAll是不仅是普通方法与同步机制,还是java两个线程中的通信机制。因为该通信机制与synchronized绑定,又需要保证对所有对象可用,所以放到Object中比较好。每个对象都可以上锁,这也就是放到Object中,而不是放到Thread类中的原原创 2022-05-28 23:04:59 · 361 阅读 · 1 评论 -
线程学习(13)-偏向锁
轻量级锁升级重量级锁,这块的内容总算是捋明白了,只要存在阻塞状态,那么肯定就是重量级锁了。必定和monitor对象中的waitSet以及entryList所相关。偏向锁,我上次写的代码中,看到了无锁,轻量级锁,重量级锁。但是却没有看到偏向锁。偏向锁其实是最常见的锁。下面说一下。偏向锁状态偏向锁其实默认就开启着,对象创建的时候,其实也应该是偏向锁状态。但是,就我上次所写的代码,默认情况下是无锁normal。问题何在?因为偏向锁的加载是一个延迟加载的过程,不会在程序启动时,立刻加载。如果想加载,原创 2022-05-28 17:14:03 · 713 阅读 · 0 评论 -
线程学习(11)-轻量级锁
上一节,就着montior把重量级锁的内容写了一下,这节写一下轻量级锁。轻量级锁与重量级锁场景首先按场景划分一下:1.使用重量级锁的场景,在一个线程持有锁资源来正在进行业务操作时,另有其它线程在操作未执行完成时去竞争当前锁资源,使用重量级锁。(锁膨胀,后期说一下)。2.使用轻量级锁的场景,在一个线程执行完成之后,释放了锁资源,此时另外的线程在这个线程结束后获取到释放的锁资源来进行操作时,使用了轻量级锁。(从偏向锁升级为轻量级锁)。3.使用偏向锁的场景,这个也说一下吧。在一个线程执行完成后原创 2022-05-26 16:42:22 · 457 阅读 · 0 评论 -
线程学习(10)-monitor
synchronized加锁操作时,是monitor在底层操作系统中完成了重量级锁的加锁操作,主要是通过了monitorEnter以及monitorExit完成这个操作的。那么synchronized与monitor是怎么关联的呢?先带个疑问。Java对象头简介以32位机器为例:在对象头中,普通对象的对象头包含Mark Word,Klass Word,而数组对象多了一个array length。Mark Word,在不同的状态下记录了不同的内容,后续会一一介绍。Klass wor原创 2022-05-26 11:35:06 · 694 阅读 · 0 评论 -
线程学习(9)- 卖票代码与转账代码
多线程在考虑线程安全时,一定要考虑临界区,即被多个线程所共享的变量,在多线程种是否发生了读写操作,如果发生了,就可能会出现线程安全问题,需要保证线程安全。卖票问题卖票问题代码如下:package com.bo.threadstudy.two;import lombok.extern.slf4j.Slf4j;import java.util.*;/** * 卖票方法的测试类,首先需要一个票站,多个窗口卖票通过这个票站对象执行 */@Slf4jpublic class Se原创 2022-05-24 19:46:41 · 202 阅读 · 0 评论 -
线程学习(8)-变量的线程安全分析
成员变量与静态变量是否线程安全如果它们没有被线程共享,则线程安全如果它们被线程共享了,存在两张情况:如果只有读操作,此时是线程安全的。如果是读写操作,则这段代码是临界区,需要考虑线程安全。package com.bo.threadstudy.two;import java.util.List;/** * 关于线程安全功能的验证 */public class ThreadSafeTest { public static void main(String[] args原创 2022-05-21 18:08:54 · 380 阅读 · 0 评论 -
线程学习(7)- synchronized总览
synchronized的使用场景,临界区以及竞态条件。原创 2022-05-21 14:03:45 · 106 阅读 · 0 评论 -
线程学习(六)-应用之统筹方法
阅读华罗庚《统筹方法》,给出烧水泡茶的多线程解决方案,提示参考图二,用两个线程(两个人协作)模拟烧水泡茶过程文中办法乙、丙都相当于任务串行而图一相当于启动了 4 个线程,有点浪费用 sleep(n) 模拟洗茶壶、洗水壶等耗费的时间附:华罗庚《统筹方法》统筹方法,是一种安排工作进程的数学方法。它的实用范围极广泛,在企业管理和基本建设中,以及关系复杂的科研项目的组织与管理中,都可以应用。怎样应用呢?主要是把工序安排好。洗水壶 1分钟 烧开水 15分钟洗茶壶 1分钟洗茶杯 2分钟拿茶叶 1分原创 2022-05-19 18:21:12 · 168 阅读 · 0 评论 -
线程学习(5)-线程的五种状态以及六种状态
线程的状态,以及简单写了下代码,简单介绍了一下原创 2022-05-19 18:03:02 · 791 阅读 · 0 评论 -
线程学习(4)-主线程和守护线程
有个守护线程的简单样例原创 2022-05-19 11:19:03 · 213 阅读 · 0 评论 -
线程学习(3)-线程常见方法
简单介绍了下Thread类中的各类方法,以及调用了方法之后,线程的类型转换原创 2022-05-19 10:47:34 · 193 阅读 · 0 评论 -
线程学习(2)-Java线程创建
线程创建方式线程创建方式,划分为三种,Thread创建,Runnable创建,以及futureTask整合Callable来实现访问,代码如下:package com.bo.threadstudy.two;import lombok.extern.slf4j.Slf4j;import org.junit.jupiter.api.Test;import org.openjdk.jmh.annotations.*;import java.util.concurrent.Callable;原创 2022-05-17 16:12:28 · 183 阅读 · 0 评论 -
线程学习(1)-进程与线程
个人线程学习资料,如果有什么不对的,还请指正,只是线程基本概念。原创 2022-05-17 11:30:15 · 166 阅读 · 0 评论 -
初学者谈线程
随手记录一下,方便与我一样的初学者理解线程。线程,可以理解为程序的运行渠道。每多一个线程,其实就多了一个渠道。就像一条河一样,我挖一条河道就是一个线程,多条河道就是多条线程。那么他的作用其实就是就是为了分担压力(应对高并发这种情况存在),就像河道一样,河道越多,水就疏通的越快,压力就越小。那么说一下线程安全,线程安全其实是对共享资源的安全保证,这样说吧,我们的系统有一个总体主存,而每一个线...原创 2019-03-22 18:47:42 · 180 阅读 · 0 评论