![](https://img-blog.csdnimg.cn/20200629022620599.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
并发编程
对多线程的相关机制进行学习和理解,为段位的晋升打下基础
大当家_白
这个作者很懒,什么都没留下…
展开
-
线程池(二) -- 源码解析ThreadPoolExecutor中的execute()方法
ThreadPoolExector实际上就是一个生产消费模式,当调用execute()方法添加任务线程时,相当于生产者生产数据元素,workers线程池中的线程执行任务线程或从阻塞队列中获取任务线程执行时,相当于消费者消费数据元素。在源码分析execute方法之前,需要弄清楚下面几个问题。1)、线程池中的线程是什么样的线程对象?2)、线程池中的线程用什么来进行存储?3)、处于等待状态的任务线程又放在那里?4)、线程池中的线程是如何获取并执行这些处于等待状态中的任务线程的?首先区.原创 2020-08-08 04:49:39 · 1273 阅读 · 0 评论 -
线程池(一) -- 通过类图简单介绍ThreadPoolExecutor
线程池用起来比较简单,但其内部就像一台仪器,需要各个部分相互协作来完成相应的功能。设计模式就用了工厂模式、策略模式、代理模式以及模板模式。ThreadPoolExecutor类图如下:原创 2020-08-07 05:53:59 · 755 阅读 · 0 评论 -
通过源码看阻塞队列之ArrayBlockingQueue
ArrayBlockingQueue是使用独占锁(ReentrantLock)实现的阻塞队列,ArrayBlockingQueue与LinkedBlockingQueue的不同之处,就是ArrayBlockingQueue底层的数据结构使用的是数组。且添加数据和获取数据用的都是同一个独占锁,所以读写并没有分离,读写操作不能并行执行。属性源码分析: /** 数组用于存储数据元素 */ final Object[] items; /** 获取元素时数据元素下标 */ .原创 2020-08-05 00:27:42 · 122 阅读 · 0 评论 -
通过源码看阻塞队列之LinkedBlockingQueue
LinkedBlockingQueue是使用独占锁(ReentrantLock)实现的阻塞队列,是线程安全的。底层使用的数据结构为单向链表。只能从队头获取元素,只能从队尾添加元素,且添加元素和获取元素都有独立的锁,从而实现读写分离,读写操作可并行执行。类图如下:属性含义:head、last:队列头节点和队列尾节点。count:队列中元素的个数,初始值为0。takeLock:获取队头元素时,使用该独占锁putLock:在队尾位置添加元素时,使用该独占锁notEmpty:出队时的原创 2020-08-04 07:10:44 · 194 阅读 · 0 评论 -
LockSupport的park() / unpark()方法与wait() / notify()方法的区别
LockSupport类是JDK种rt.jar包中的工具类,它主要的作用是挂起和唤醒,该工具类是创建锁和其他同步类的基础。LockSupport类采用的是许可证机制,该类与使用它的类都会关联一个许可证,在默认情况下调用LockSupport类方法的线程是不只有许可证的。LockSupport是使用UnSafe类实现的。LockSupport的park()方法与unpart(Thread thread)方法park():线程调用LockSupport.park()方法,首先需要判断该线程是否.原创 2020-08-02 01:51:58 · 2133 阅读 · 0 评论 -
多线程相关锁概念
乐观锁与悲观锁悲观锁:指数据被外界修改持保守态度,认为数据很容易就会其他线程修改,所以数据在处理前先对数据进行加锁,并在整个数据处理过程中,使数据处于锁定状态。在实际的开发过程中,悲观锁往往依靠数据库的锁机制,即在数据库中,在对数据记录操作前给记录加排它锁。如果获取锁失败,则说明数据正被其他线程修改,当前线程等待或者抛出异常。如果获取锁成功,则对记录进行操作,然后提交事务后释放排它锁。乐观锁是相对悲观锁来说的,它认为数据在一般情况下不会发生冲突,所以在访问记录前不会加排它锁,而是在进行数据.原创 2020-08-01 10:46:40 · 128 阅读 · 0 评论 -
synchronized、volatile以及CAS的区别
在讲解synchronized、volatile、CAS的区别之前,需要弄明白什么共享资源、什么是线程安全、线程间的可见性问题以及Java操作的原子性。弄明白这些问题可以加深你对synchronized、volatile、CAS的理解。下面我会先对这些问题进行简单的说明,什么是资源共享?同一个资源被多个线程所持有 或者说多个线程可以访问该资源,这样的资源称之为共享资源。什么线程安全?就是指多个线程同时读写同一个资源,并没有使用任何的同步措施,导致出现脏数据或者不可预见的结果。..原创 2020-07-30 22:27:26 · 1863 阅读 · 1 评论 -
通过源码看ThreadLocal
ThreadLocal提供了线程的本地变量。每个线程在使用这个变量的时候,都会在当前线程中创建这个变量的本地副本。ThreadLocal的作用:它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。ThreadLocal的简单使用:public class ThreadLocalTest { ThreadLocal<String> strVal= new ThreadLocal<>(); ThreadLocal<Integ..原创 2020-07-30 05:15:43 · 117 阅读 · 0 评论 -
基础篇 --死锁之哲学家就餐问题实现
死锁:是指两个或者两个以上的线程在执行过程中,因为争夺资源而造成的互相等待的现象,在无外力的情况下,这些线程会一直相互等待而无法继续运行下去(摘自《Java并发编程之美》)死锁:某个任务在等待另一个任务,而后者又等待别的任务,这样一直下去,直到链条上的任务又在等待第一个任务释放锁,这得到了一个任务之间相互等待的连续循环,没有哪个线程能继续,被称之为死锁(摘自《Java编程思想》)产生死锁的四个必备条件:1、互斥条件:线程使用的资源中至少有一个不能共享2、线程持有资源并等待另一个资源.原创 2020-07-02 18:54:21 · 410 阅读 · 0 评论 -
基础篇--wait()、notify()实现生产-消费者模式
wait()/notify()/notifyAll()方法:wait()方法:线程调用wait()方法,线程将进入阻塞状态,但与sleep()方法不同的时,调用wait方法会释放锁资源。当调用notify()方法或者notifyAll()方法后,线程会从阻塞状态转换可运行状态。notity()方法/notifyAll()方法: 唤醒等待中的线程,经典场景:生产-消费者模式模拟场景:一个餐馆,由一个厨师和一个服务员,接到订单后,服务员需等到厨师做好食物,厨师准备好食物后,会通知服务员取走食物。原创 2020-07-02 18:35:07 · 288 阅读 · 0 评论 -
基础篇--优雅的退出线程的方式java
方法一:interrupt()方法和isInterrupt()方法配合使用java中的线程中断是一种线程的协作模式,通过设置线程的中断标志并不能直接终止该线程,而是被中断的线程根据中断状态自行处理。interrupt()方法:中断线程,只是设置一个线程标识,并不能中断线程的执行。例如:运行线程A时。在线程B中调用线程A的interrupt()方法来设置线程A的中断标识为true。线程A实际上并没有中断,还会继续执行。注:当线程调用wait()、sleep()和join()方法,线程进入阻塞状态后原创 2020-07-02 18:23:45 · 645 阅读 · 0 评论 -
基础篇 -- 并发编程必备知识点
创建线程的方式:1)、实现Runnable接口 2)、继承Thread类守护线程:守护线程运行再程序后台。当主线程结束的时候,不管守护线程有没有执行完,守护线程都会结束,并不会影响虚拟机的退出。什么样的线程是守护线程?当线程对象A调用setDaemon()方法设置为true时,该线程即为守护线程。即。A.setDaemon(true)。A就会标记为守护线程优先级别:线程得最大优先级别为10,最小优先级别是1,默认优先级别为5。优先级别高得线程获取cpu资源得机率比低优先级别...原创 2020-07-02 17:58:31 · 114 阅读 · 0 评论