
并发编程
文章平均质量分 64
并发编程的学习之路
大多使用思维导图
qq_20009015
欢迎关注我的公众号《程序员与王子喵》
展开
-
java并发包中ThreadLocalRandom类原理剖析
java并发包中ThreadLocalRandom类原理剖析Random类及其局限性ThreadLocalRandom类是jdk7在juc包下新增的随机数生成器,它弥补了Random类在多线程下的缺陷。jdk7之前包括现在,Random类都是使用比较广泛的随机数生成器,Math中随机数生成也是使用的Randmon实例 public Random() { this(seed...原创 2019-08-10 16:35:01 · 256 阅读 · 0 评论 -
并发编程基础进阶(下)
Unsafe类Unsafe类中的重要方法jdk的rt.jar包中的Unsafe类提供了硬件级别的原子性操作,Unsafe类中的方法都是native方法,它们用JNI的方式访问本地c++实现库。long objectFiedOffset(Field field)方法返回指定的变量在所属类中的内存偏移地址(即内存地址),该偏移地址仅仅在该Unsafe函数中访问指定字段时候使用。例如:vav...原创 2019-07-28 17:48:36 · 259 阅读 · 0 评论 -
并发编程基础进阶(上)
1.什么是多线程并发编程首先要澄清并发和并行的概念,并发和指同一个时间段内多个任务同时都在执行,并且都没有执行结束。而并行是在单位时间内多个任务同时在执行。并发任务强调在一个时间段内同时执行,而一个时间段由多个单位时间累积而成,所以说并发的多个任务在单位时间内不一定同时执行。在单cpu的时代多个任务都是并发执行,因为单个cpu同时只能执行一个任务。在单个cpu时代多任务是共享一个cpu的,...原创 2019-07-19 23:35:20 · 647 阅读 · 4 评论 -
ThreaLocal和InheritalblThreadLoal的用法,子线程获取父线程的本地变量
ThreaLocal中设置的变量,在子线程中无法获取public class ThreadLocalExtendTest { //创建线程变量 public static ThreadLocal<String> threadLocal=new ThreadLocal<>(); public static void main(String[]...原创 2019-07-17 01:00:02 · 313 阅读 · 0 评论 -
ThreadLocal介绍和原理解析
ThreadLocal介绍:多线程访问一个共享变量时特别容易出现并发问题,特别是在多个线程需要对一个共享变量进行进入时。为了保证线程安全,一般使用着在访问共享变量时需要进行适当的同步ThreadLocal可以做到,当创建一个变量之后,每个线程对其进行访问的时候,访问的是自己线程的变量。ThreadLocal是jdk包提供的,它提供了线程本地变量,也就是如果你创建了ThreadLocal变量,...原创 2019-07-16 01:38:13 · 553 阅读 · 0 评论 -
线程死锁分析
什么是线程死锁?死锁是指两个或者两个以上的线程在执行过程中,因为争夺资源而造成的互相等待的现象。如果没有外力作用下,这些线程会一直互相等待而无法继续运行下去。比如说线程A持有资源1,等待资源2线程B持有资源2,等待资源1且双方都不愿意放弃自己所持有的资源死锁的四个条件:1.互斥条件:资源只能同时被一个线程占用,如果此时有其他线程想要获取资源,则必须等待,直到占有资源的线程释放该资源2...原创 2019-07-14 21:05:00 · 258 阅读 · 0 评论 -
基于数组实现阻塞队列
基于数组实现的话,需要额外两个指针,一个指向头元素,一个指向尾元素。出的时候从头元素出去,入的时候从尾元素入。即出的时候tail指针+1,入的时候尾指针+1 ,因此使用一个环形队列最好,不会浪费空间也不需要挪动元素位置。因为是环形队列,因此tail在最后一个位置的时候,再进来一个元素,如果队列不满,就会挪到第一个位置上。计算环形队列的位置公式为 : tail = (tail + 1...原创 2019-07-14 18:41:44 · 440 阅读 · 0 评论 -
java中的守护线程与用户线程
java中的线程分为两类,分别为daemon线程和user线程,在jvm启动时候会调用main函数,main函数所在的线程就是一个用户线程,在JVM内部还启用了很多守护线程,比如说垃圾回收线程。当最后一个非守护线程结束时候,JVM会正常退出,而不管当前是否有守护线程,也就是说守护线程是否结束并不影响JVM退出。即只要有一个用户线程还没结束,正常情况下JVM就不会退出。因此main线程结束之后...原创 2019-07-14 13:24:36 · 463 阅读 · 0 评论 -
理解线程上下文切换
在多线程编程中,线程个数一般都大于cpu个数,而每个cpu同一时刻只能被一个线程使用,为了让用户感觉多个线程是在同时执行的,cpu资源采用了时间片轮转的策略,也就是给每一个线程分配一个时间片,线程在时间片内占用cpu执行任务。当前线程使用时间片之后,就会处于就绪状态并让出cpu让其他线程占用,这就是上下文切换,从当前线程的上下文切换到了其他线程。那么就有一个问题,让出cpu的线程等下次轮到自己占...原创 2019-07-14 12:31:20 · 797 阅读 · 0 评论 -
isInterrupted和Interrupted的区别
boolean isInterrupted()方法1.isInterrupted是实例方法检查当前线程是否被中断,如果是返回true,否则返回false,不会清除中断状态boolean interrupted()方法1.interrupted是Thread的静态方法检测当前线程是否中断,如果是返回true,否则返回false。与isInterrupted不同的是,该方法如果发现当前线程...原创 2019-07-14 01:21:42 · 224 阅读 · 0 评论 -
interrupt的用法
java中的线程中断是一种线程间的协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是被中断的线程根据中断状态自行处理。void interrupt()方法:中断线程,例如当线程A运行时,线程B可以调用线程A的interrupt()方法来设置线程A的中断标志为true并立即返回。设置标志仅仅是设置标志,线程A实际上并没有被中断,它会继续往下执行。如果线程A因为调用了wait系列的函...原创 2019-07-13 22:08:40 · 5199 阅读 · 0 评论 -
yield方法的用法
让出cpu执行权的yield方法Thread类中有一个静态的yield方法,当一个线程调用yield方法时,实际就是暗示线程调度器当前请求让出自己的cpu使用,但是线程调度器可以无条件忽略这个暗示。操作系统为每一个线程分配一个时间片来占有cpu,正常情况下当一个线程把分配给自己的时间片用完之后,线程调度器才会进行下一轮的线程调度,而当一个线程调用了Thread类的静态方法yield时,是在告诉...原创 2019-07-13 20:26:41 · 4247 阅读 · 0 评论 -
sleep方法的使用,进入sleep状态不释放锁
Thread类中的静态方法sleep(),当一个执行中的线程调用了Thread的sleep()方法后,调用线程会暂时让出时间的执行权,这期间不参与cpu的调度,但是该线程持有的锁是不让出的。时间到了会正常返回,线程处于就绪状态,然后参与cpu调度,获取到cpu资源之后就可以运行。如果在睡眠期间,其他线程调用了该线程的interrup()的方法中断了该线程,则该线程会调用sleep方法的地方抛出I...原创 2019-07-13 18:55:30 · 11662 阅读 · 9 评论 -
join方法的使用
join方法是Thread类直接提供的,线程A调用线程B的join方法后,会被阻塞,等待B完成。如果此时其他线程调用了线程A的interrupt()方法,线程A会抛出InterruptException异常 public static void main(String[] args) throws InterruptedException { Thread threadOne=...原创 2019-07-13 18:24:27 · 737 阅读 · 0 评论 -
notify和notifyAll函数解析
public class NotyfyDemo { private static volatile Object resourceA = new Object(); public static void main(String[] args) { new Thread(() -> { synchronized (resource...原创 2019-07-13 17:24:53 · 1196 阅读 · 0 评论 -
wait函数-思维导图
原创 2019-07-13 13:04:50 · 335 阅读 · 0 评论 -
wait状态下线程的中断
当一个线程调用共享对象的wait()方法被阻塞挂起后,其他线程中断了该线程,则该线程会在wait所在的行抛出InterruptedException异常并返回, 不会继续往下执行/** * @ClassName WaitNotifyInterupt * @Author laixiaoxing * @Date 2019/7/13 下午12:02 * @Description 线程中断的例子...原创 2019-07-13 12:10:39 · 2243 阅读 · 3 评论 -
线程死锁的例子
当前线程调用共享变量的wait()方法之后只会释放当前共享变量上的锁,比如说XX.wait(). 只会释放XX上的监视器锁,如果当前线程还持有其他共享变量的锁,这些锁是不会释放的。因此可以模拟一下,长期获取不到锁的情况情况1:线程A资源一直不释放,另线程B则一直请求资源解决方法就是打破一直持有的条件,比如说超时释放或者请求超时就放弃package deadLock;/** * @C...原创 2019-07-13 11:18:27 · 595 阅读 · 0 评论 -
使用wait和notfy实现最简单的生产者-消费者阻塞队列
使用synchronized和wait以及notify实现生产者-消费者模式的阻塞队列队列满了则生产者等待队列每放入一个元素就调用一次notifyAll唤醒消费线程队列空了则消费者等待队列每移除一个元素则调用notifyAll唤醒生产线程class BlockQueue { private int max = 10; private List<String>...原创 2019-07-12 14:09:54 · 327 阅读 · 0 评论 -
线程的虚假唤醒(Spurious Wakeups)以及解决方案
网上一堆误人子弟的文章,有说是别的线程唤醒了这个线程,然后唤醒后唤醒条件被某个线程改了导致不成立这种说法,还有说的是唤醒来后没有执行条件,无效唤醒等等等,都在乱讲。先说结论:虚假唤醒(Spurious Wakeups):一个线程可以从挂起状态变为可以运行状态(也就是被唤醒)即使该线程没有被其他线程调用notify(),notify()方法进行通知,或者被中断,或者等待超时。注意:解决方法...原创 2019-07-12 09:28:11 · 1016 阅读 · 0 评论 -
线程的创建和运行有几种方式
原创 2019-07-11 12:21:36 · 196 阅读 · 0 评论 -
如何看源码?
作为一名程序员,不管是学习还是工作,各种框架都是少不了的,对于框架,不止是要会用,也要掌握其原理,而且面试往往也会重点考察原理,因此学会看源码就是一种必不可少的能力了。 万事开头难,现在开始尝试按照以下的方法,一步步来,最终能画出调用时序图和类图的时候,说明就已经对这个框架了然于胸了。...原创 2019-07-10 12:45:37 · 456 阅读 · 1 评论 -
什么是线程?
原创 2019-07-11 08:11:53 · 119 阅读 · 0 评论 -
两个线程分别打印26个字母的元音(a,e,i,o,u) 和辅音(其他),要求按字母序输出
使用conditionnpublic static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCond...原创 2019-06-06 16:45:42 · 1415 阅读 · 4 评论 -
手写单例模式的线程池实践
package com.souche.sfs.server.common.util;import lombok.extern.slf4j.Slf4j;import java.io.IOException;import java.util.concurrent.*;/** * @ClassName CheckAccountThreadPoolUtil * @Author laix...原创 2019-05-08 23:27:23 · 1393 阅读 · 0 评论 -
线程的停止和中断
线程停止有四种种情况:1.run运行结束2.异常退出3.stop强制中止,这个不推荐使用,存在风险,比如说扫尾清理工作未完成,关闭资源未完成 就退出了。4.interrupt方法中断线程, 需要主动编码配合,写中断逻辑,但是可控。调用interrupt()方法只是打了个退出标志,并非真正的退出,退出逻辑需要自己写。package ThreadCheat1.interrupt;/**...原创 2019-04-22 13:01:25 · 3103 阅读 · 0 评论 -
自定义线程池的实践
/** * 自定义线程池 */public class UserDefinedThread { public static void main(String[] args) {//使用ThreadPoolExecutor定义自己的想要的线程池//核心线程数,最大线程数,最大空闲时间,时间单位,阻塞队列,线程工厂,拒绝策略 ExecutorService exec...原创 2019-03-18 02:09:37 · 171 阅读 · 0 评论 -
线程交替打印奇偶数(wait和notify实现以及原理简介)
wait和notify是Object的方法,不是thread的方法。Object,notify()作用是唤醒持有这个Object对象锁的线程,Object,wait()作用是让当前线程进入阻塞状态。因此 notify和wait只能用于synchronized内部,因为synchronized会指定对象锁,而wait的前提是当前线程持有锁。如果不在synchronized代码包含范围内会报...原创 2019-03-18 00:24:10 · 3986 阅读 · 1 评论 -
线程交替打印奇偶数(信号量Semaphore实现)
实现方法一,信号量思路:两个线程都持有相同的一个信号量,奇数线程启动,获取信号量,然后打印完,释放信号量,再休眠,然后偶数线程启动,获取信号量,然后打印完,释放信号量package demo6;import java.util.concurrent.Semaphore;/** * @ClassName AlternatePrinting * @Author laixiaoxing...原创 2019-03-17 19:34:55 · 2507 阅读 · 0 评论 -
线程池各个参数详解以及如何自定义线程池
一:为什么要自己定义线程池虽然jdk提供了几种常用特性的线程池给我们,但是很多时候,我还是需要自己去自定义自己需要特征的线程池。并且阿里巴巴规范手册里面,就是不建议使用jdk的线程池,而是建议程序员手动创建线程池。为什么呢?原文如下【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规...原创 2019-01-06 21:59:46 · 22305 阅读 · 1 评论 -
jdk提供的几种线程池的介绍
Executor框架提供了各种类型的线程池。ExecutorService 继承了Executor接口,初步定义了线程池内的方法。然后 ,AbstractExecutorService又实现了ExecutorService里面定义的方法。再最后ThreadPoolExecutor 继承了AbstractExecutorService,里面是更为细致的实现。jdk定义了一个Executors工...原创 2019-01-05 18:00:37 · 1171 阅读 · 0 评论 -
jdk的线程池框架简要分析
jdk提供了一套Executor框架,其本质就是线程池。首先是public interface Executor {//执行一个实现了Runnable接口的任务 void execute(Runnable command);Executor接口是所有线程池的父接口然后 ExecutorService 继承了Executor接口,初步定义了线程池内的方法public inte...原创 2019-01-05 11:55:42 · 200 阅读 · 0 评论 -
为什么要用线程池
1.为什么要用线程池多线程的情况下确实可以最大限度发挥多核处理器的计算能力,提高系统的吞吐量和性能。但是如果随意使用线程,对系统的性能反而有不利影响。比如说 new Thread(new Runnable() { @Override public void run() { try { ...原创 2019-01-05 11:54:25 · 5228 阅读 · 0 评论 -
从赛马游戏看CyclicBarrier,从斗地主看CountDownLatch
CyclicBarrier是栅栏,效果就是让多个线程都执行到某个指定的点之后,再一起继续执行。与CountDownLatch有点类似,最大的区别是CyclicBarrier可以循环使用。这里举例两个场景,一个是斗地主,需要三个玩家都入场之后才可以开始。 另一个是赛马,多匹马一起跑,最先到达终点的算赢。这里用线程分别表示玩家和马。三人斗地主代码如下:(需要三个玩家入场之后才能发牌)publi...原创 2018-12-02 21:20:45 · 393 阅读 · 0 评论 -
IO密集型和cpu密集型的多线程总结
线程是否越多越好? 分析如下:一个计算为主的程序(专业一点称为CPU密集型程序)。多线程跑的时候,可以充分利用起所有的cpu核心,比如说4个核心的cpu,开4个线程的时候,可以同时跑4个线程的运算任务,此时是最大效率。但是如果线程远远超出cpu核心数量 反而会使得任务效率下降,因为频繁的切换线程也是要消耗时间的。因此对于cpu密集型的任务来说,线程数等于cpu数是最好的了。如果是一个磁盘或...原创 2018-11-16 16:36:59 · 17816 阅读 · 1 评论 -
java并发编程实战从因数分解看多线程(下)
java并发编程实战从因数分解看多线程从之前的那篇文章中我们已经验证了多线程可以显著提高程序的效率,但并非没有限制。那么要如何才能更进一步的提升这个程序的效率,答案是利用缓存。我们将已经进行过因数分解的数字和它分解之后的结果存起来,如果下次任务中发现这个数字已经被分解过了,就直接从缓存里拿,而没有必要继续去计算。我们选用map做为缓存,改造后的因数分解的代码如下:public class...原创 2018-09-27 17:01:44 · 312 阅读 · 0 评论 -
java并发编程实战之从因数分解看多线程(上)
java并发编程实战之从因数分解看多线程(上)这篇博文主要通过对多个大数的因数分解进行实践,进而引出初步的多线程的一些用法和思考。1.因数分解因数分解是对一个数字m,找出它所有的因数的过程,比如说数字6 因数分解之后为 2x32.为何选择因数分解因为因数分解是一个很费事的计算过程,目前没有很好的算法可以提高效率,可以很好的用来模拟复杂计算处理过程,以便于我们明显的去观察在不同的情...原创 2018-09-26 02:53:52 · 604 阅读 · 0 评论 -
线程池异常处理详解,一文搞懂
在实际开发中,我们常常会用到线程池,但任务一旦提交到线程池之后,如果发生异常之后,怎么处理? 怎么获取到异常信息?而不是任务提交之后,消失的无影无踪。要知道以上答案,先看下 线程池里面的线程发生异常之后会发生什么。我们先通过工具类Executors创建一个简单的线程池,里面核心线程数为1 ExecutorService executorService=Executors.newFixedT...原创 2019-09-06 17:03:22 · 8964 阅读 · 7 评论