![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
并发编程
并发编程
一只小P熊
这个作者很懒,什么都没留下…
展开
-
【P说】深入理解JDK中的线程池
简介线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后已经创建好的线程会在队列中获取并自动启动这些任务。为什么要使用线程池提高线程的可管理性,如果使用new Thread的方式,那么每一个任务就会新建一个线程,线程数量不可控,使用线程池,可以明确池子中创建多少个线程。省去线程创建和销毁时占用的资源。降低线程的执行时间,省去了线程创建和销毁的时间。使用new Thread的方式,任务执行时间为线程创建T1 + 任务执行T2 + 线程销毁T3,使用线程池为只有T2。实现自己的线程池线原创 2020-05-25 11:18:01 · 125 阅读 · 0 评论 -
【P说】深入理解Java阻塞队列
简介阻塞队列是一种队列,一种可以在多线程环境下使用,并且支持阻塞等待的队列。当队列满的时候,插入元素的线程被阻塞,直达队列不满。队列为空的时候,获取元素的线程被阻塞,直到队列不空。方法java的阻塞队列,要实现BlockingQueue接口:public interface BlockingQueue<E> extends Queue<E> { boolean add(E e); boolean offer(E e); void put(原创 2020-05-22 17:33:03 · 136 阅读 · 0 评论 -
【P说】JDK 1.8 ConcurrentHashMap分析
简介相对JDK 1.7,ConcurrentHashMap在JDK 1.8有了很大的优化改动,底层的实现由原来的“segement数组+table数组+链表”改为了“node数组+链表或者红黑树”。关于ConcurrentHashMap 在JDK1.7的分析,可以查看:【P说】JDK 1.7及以前ConcurrentHashMap分析数据结构可以看到,在JDK 1.8的时候ConcurrentHashMap在底层实现上取消了原本的segement数组,改为了“node数组+链表或者红黑树”的实现。原创 2020-05-21 17:36:38 · 225 阅读 · 0 评论 -
【P说】JDK 1.7及以前ConcurrentHashMap分析
简介ConcurrentHashMap可以理解为多线程环境下HashMap,它是线程安全的。ConcurrentHashMap在JDK 1.7和JDK 1.8上的实现有很多区别,本文主要说明ConcurrentHashMap在JDK 1.7的实现。与HashTable的区别JDK还提供了HashTable,也是线程安全的,那么为啥我们不用HashTable,而是使用ConcurrentHashMap。因为Hashtable容器使用synchronized来保证线程安全,所以在线程竞争激烈的情况下Has原创 2020-05-20 18:12:27 · 233 阅读 · 0 评论 -
【P说】多线程HashMap产生死循环
简介在1.7及以前,使用HashMap进行put操作时,当元素超过阈值时,会触发resize操作,这时候可能就会出现死循环的情况,导致CPU占用率达到100%。原因归根结底,就是JDK 1.7链表新节点采用的是头插法,这样在线程一扩容迁移元素时,会将元素顺序改变,导致两个线程中出现元素的相互指向而形成循环链表,JDK 1.8之后采用了尾插法,从根源上杜绝了这种情况的发生。数据结构首先,我们要先了解HashMap的数据结构,HashMap的主干是一个Entry数组。Entry是HashMap的基本组原创 2020-05-20 16:07:29 · 303 阅读 · 0 评论 -
【P说】深入理解AQS
简介AQS全称为AbstractQueuedSynchronizer,是一个抽象类,主要是通过继承的方式来使用,其内部维护了一个同步队列,AQS是一个用来实现同步锁以及其他涉及到同步功能的核心组件。使用的设计模式AQS使用了模板方法设计模式,这里只做大致的介绍,所谓模板模式,就是有一个抽象类公开定义了执行它的方法的方式/模板。继承它的子类需要重写方法的具体细节,但是调用将以抽象类中定义的方式进行。比如,一个烧水的过程,在模板模式中,抽象类会定义一整个过程,包括拿壶,倒水,开火等,而继承它的子类负责实现原创 2020-05-19 16:34:37 · 1345 阅读 · 0 评论 -
【P说】显示锁、ReentrantLock
Synchronized缺陷当线程A拿到sync锁以后,线程B只能一直等待,知道线程A使用完并释放锁。当我们进行读写操作时,读操作和读操作之间实际上是不会有冲突的,如果采用synchronized关键字实现同步的话,就会导致当多个线程都只是进行读操作时,也只有一个线程在可以进行读操作,其他线程只能等待锁的释放而无法进行读操作。无法尝试的去获得锁。Lock意义可以说,Lock的出现就是为了解决synchronize的缺陷,实际上,synchronized在经过一段时间的优化之后,效率已经非常高了原创 2020-05-16 10:39:56 · 131 阅读 · 0 评论 -
【P说】原子操作CAS
简述CAS(Compare and Swap,比较并交换)是一个CPU指令,其语义为:“如果地址V上的值和期望的值A相等,就给地址V赋给新值B,如果不是,不做任何操作。”,CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。同synchronized相比Synchronized是一个独占锁,属于悲观锁(假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致原创 2020-05-15 10:20:29 · 234 阅读 · 0 评论 -
【P说】Exchanger
简述Exchanger用来线程之间进行数据交换,只能两个线程进行数据交换。例子public class TestExchanger { static Exchanger<String> exchanger = new Exchanger<>(); private static class Thread1 extends Thread { @Override public void run() { Stri原创 2020-05-14 12:06:22 · 96 阅读 · 0 评论 -
【P说】信号量Semaphore
简述Semaphore是线程同步的辅助类,可以控制当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如通过 Semaphore 限流。使用private final static int POOL_SIZE = 10; private final Semaphore useful,useless;//useful表示可用的数据库连接,useless表示已用的数据库连接 public DBPoolSemaphore() { this. usef原创 2020-05-14 10:42:27 · 139 阅读 · 0 评论 -
【P说】浅谈CountDownLatch与CyclicBarrier
CountDownLatchCountDownLatch是一个同步工具类,用来协调多个线程之间的同步,CountDownLatch的作用与join方法类似,可以让一个线程在收到其他线程的通知之后再进行执行,CountDownLatch的作用比join更强大,因此是加强版的join。CountDownLatch就是一个计数器,只有在计数为0之后,被阻塞的方法才会开始运行。方法CountDownLatch(int count):传入count,当count的值被递减至0时,被阻塞的线程就开始执行。awa原创 2020-05-14 10:16:16 · 169 阅读 · 0 评论 -
【P说】浅谈Fork/Join
简述ForkJoin是由JDK1.7后提供多线并发处理框架。它的基本思想是分而治之。分而治之规模为N的问题,N<阈值,直接解决,N>阈值,将N分解为K个小规模子问题,子问题互相对立,与原问题形式相同,将子问题的解合并得到原问题的解。ForkJoin的工作秘取(work-stealing)由于ForkJoin的执行时多线程的,因此总会出现,有的线程已经执行完了,其他线程还没执行或者还在执行的情况,这个时候执行完的线程假如只是等待另一个线程执行完,效率就太低了。因此,在线程A执行完毕后,原创 2020-05-13 10:34:41 · 334 阅读 · 0 评论 -
【P说】wait、notify、notifyAll使用
简述wait、notify、notifyAll是Object提供的方法,通过这三个方法可以实现线程的等待和通知机制。public final native void notify();public final native void notifyAll();public final native void wait(long timeout) throws InterruptedException;public final void wait() throws InterruptedExcepti原创 2020-05-12 10:22:54 · 152 阅读 · 0 评论 -
【P说】ThreadLocal
https://www.cnblogs.com/fsmly/p/11020641.html原创 2020-05-12 09:49:21 · 122 阅读 · 0 评论 -
【P说】Volatile
https://www.cnblogs.com/dolphin0520/p/3920373.html原创 2020-05-12 09:04:49 · 215 阅读 · 0 评论 -
【P说】sleep 与 yield
sleep让出指定时间的执行权,也就是在这期间不参与 CPU 的调度,但是该线程所拥有的监视器资源,比如锁还是持有不让出的。等时间到了之后就重新变成就绪状态。yield调用 yield 方法时,当前线程会让出 CPU 的使用权,然后处于就绪状态,此时该线程完全有可能再一次获得CPU的使用权。关于sleep与yield方法对线程持有锁资源的影响都不会让出对应线程所持有的锁资源。...原创 2020-05-11 11:57:50 · 199 阅读 · 0 评论 -
【P说】守护线程
概念所谓守护线程,就是用来“守护”其他线程的线程,其实就是服务于其他的线程,守护线程的终止与用户现场有关,当所有用户线程都执行完毕时,不管守护线程有没有执行完毕都会被停止。例子public class DaemonThread { static class TestThread extends Thread{ @Override public void run() { while (true){ Syst原创 2020-05-11 11:47:31 · 100 阅读 · 0 评论 -
【P说】终止线程执行
协作式中断在以前的JDK版本中,Thread类包含stop() ,suspend(), destroy() ,resume()方法可以操作线程,其中stop方法强行终止正在运行或挂起的线程,调用这个方法是非常危险的,就跟直接关掉计算机电源一样,因此这些方法现在都已经被弃用,取而代之的是interrupt() 、 isInterrupted()、static方法interrupted(),通过这些办法中断线程是属于协作式的中断,既停不停止由线程本身决定。中断线程执行的方法自定义标识public cla原创 2020-05-11 11:24:57 · 149 阅读 · 0 评论 -
【P说】Java三种启动线程的方法
import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/** * @author Chris Wu * @date 2020/5/9 9:49 */public class ThreeThreadMethod { //继承Thread //优点:可以在方法中通过this调用Thread的原创 2020-05-09 12:16:14 · 156 阅读 · 0 评论 -
【P说】并发与并行
并行并行是指同一时间可以执行的线程数量,注意这里强调的是同时,假如有一块八核的CPU,那么它的并行数为8,因为它同时可以跑八个线程。并发与并行不同,并发强调的是单位时间内,也就是一段时间内跑了多少个线程,同样假设有一块八核的CPU,同时一个线程需要20ms跑完,那么100ms内的并发数就为:8(CPU核心数)*5(一个核心100ms可以跑的线程)= 40。区分关键并行强调的是同时,而并发强调的是一段时间内。例子以打饭为例子,现在有两个打饭的窗口。同时,只有两个人可以打饭,那么2就是并行数。假如原创 2020-05-09 09:37:32 · 1859 阅读 · 0 评论 -
守护线程与用户线程
简述Java 中的 线程分为两类,分别为 daemon 线程(守护线程〉和 user 线程(用户线程)。在 JVM 启动时会调用 main 函数, main 函 数所在的钱程就是一个用户线程,其实在 JVM内部同时还启动了好多守护线程, 比如垃圾回收线程。区别当最后一个非守护线程结束时, NM 会正常退出,而不管当前是否有守护线程 ,也就是说守护线程是否结束并不影响 NM 的退出。言外之意,...原创 2020-01-07 16:20:27 · 67 阅读 · 0 评论 -
死锁的产生与避免
什么是死锁死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去。死锁的产生必须具备以下四个条件:互斥条件: 指线程对己经获取到的资源进行排它性使用 , 即该资源同时只由 一个线程占用。请求并持有条件 : 指一个线程己经持有了至少一个 资源 , 但又提出了新的资源请求 ,而新资源己被其他线程占有,所 以...原创 2020-01-07 16:14:40 · 115 阅读 · 0 评论 -
JAVA线程相关常见方法
简述本文主要介绍wait()、notify()、notifyAll()、join()、sleep()、yield()的含义与用法。wait()当线程调用一个共享变量(对象锁)的wait方法时,该线程会被阻塞挂起,直到发送以下事件:其他线程调用该共享变量(对象锁)notify()、notifyAll()方法其他线程调用该线程的interrupt方法。注:如果调用 wait()方法...原创 2020-01-07 16:07:43 · 102 阅读 · 0 评论