java并发编程的艺术
大龄毕业生
大龄毕业生学习中
展开
-
线程池基本概念
线程池的处理流程如果当前运行的线程小于corePOOLSize,则创建线程执行任务(需要获取全局锁)运行的线程多余等于corePoolSize,将任务加入BlockingQueue。如果无法加入BlockingQueue(队列已满),则创建新的线程来处理任务。如果创建新的线程使得当前运行的线程超出maximumPoolSize,任务将被拒绝。...原创 2020-11-12 23:34:48 · 133 阅读 · 0 评论 -
可重入锁、读写锁
ReentrantLock:重入锁。表示该锁能够支持一个线程对资源的重复加锁.任意线程在获取到锁之后能够再次获取该所而不会被锁阻塞。之前写的Mutex是一个不支持的重入的独占锁。实现可重入线程再次加锁:锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次获取。锁的最终释放:线程重复N此获取了锁,随后在第N次释放该锁后,其他线程能够获取到该锁。锁的最终释放要求锁对于获取进行计数增加,计数表示当前锁被重复获取的次数,而被锁释放的时候,计数自减,当计数等于0的时候表示锁已经成功释放。 f原创 2020-11-11 22:52:39 · 403 阅读 · 1 评论 -
AQS队列同步器的实现分析-共享锁
共享式同步状态的获取与 释放共享式获取与独占式的区别在于同一时刻能否有多个线程同时获取到同步状态。写操作要求对资源的独占式访问。读操作可以是共享式访问。左边:共享式访问资源,其他共享式访问都被允许,而独占式被阻塞右边:独占式。同一时刻,其他访问都被阻塞。 public final void acquireShared(int arg) { if (tryAcquireShared(arg) < 0) doAcquireShared(arg);原创 2020-11-10 23:06:52 · 117 阅读 · 0 评论 -
AQS队列同步器的实现分析-独占锁
同步队列:感觉全部都是特别重要的,就都加粗了。排版不好看。尴尬同步器依赖内部的同步队列(一个FIFO双向队列)来完成同步状态的管理,当前线程获取同步状态时失败时,同步器会将当前线程和等待信息构造成一个NODE节点并将其放入同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态。可以看到:同步器包含:一个指向头结点的引用,一个指向尾节点的引用。为了保证获取同步状态失败的线程加入队列线程安全,用了CAS的方法这是尾节点。首节点是获取同步状态成功的节点。首节点原创 2020-11-10 00:07:01 · 95 阅读 · 0 评论 -
锁-独占锁、同步队列器
Lock接口锁是用来控制多个线程访问共享资源的方式。一个锁可以防止多个线程同时访问共享资源(读写锁,允许多个线程并发的访问共享资源) public static void main(String[] args) { Lock lock = new ReentrantLock(); lock.lock(); try { } finally { lock.unlock(); } }这是锁的原创 2020-11-08 22:26:59 · 133 阅读 · 0 评论 -
终于到线程池了
public interface ThreadPool<Job extends Runnable> { //执行一个job这个job需要实现runnable void execute(Job job); //关闭线程池 void shutdown(); //增加工作者线程 void addWorkers(int num); //减少工作者线程 void deleteWorkers(int num); //获取正在等待原创 2020-11-08 14:00:41 · 90 阅读 · 0 评论 -
线程间通信-java并发编程的艺术
volatile synchroizedjava支持多个多个线程同时访问一个对象或者对象的成员变量,由于每个线程都可以拥有这个变量的拷贝,这样的目的在于加速程序的执行。所以,一个线程看到的变量的并不一定就是最新的。volatile可以修饰字段(成员变量),就是告知程序任何对该变量的访问都需要从共享内存中获取,对他的改变必须同步刷新到共享内存(主内存),保证所有线程对这个变量的可见性。synchorized可以修饰方法或者修饰代码块,主要就是确保多个线程在同一时刻,只能有一个线程处于方法或者代码块中,原创 2020-11-08 01:08:26 · 157 阅读 · 0 评论 -
java并发编程的艺术-安全的终止线程
传统的suspend()方法,在调用后,线程不会释放已经战友的资源比如锁之类的,而是占着资源休眠,这样容易死锁。stop方法在终结一个线程的时候不会保证线程的资源正确释放,通常是没有给予线程完成资源释放的机会,因此,程序可能存在不确定。中断就是一个合适的取消或者停止任务的方法。除了中断,还可以利用boolean变量来控制是否需要停止任务并终止该线程。public class ShutDown { public static void main(String[] args) throws In原创 2020-11-07 22:07:35 · 108 阅读 · 0 评论 -
java并发编程的艺术-java并发编程基础
线程:操作系统的最小调度单位(轻量级进程)。在一个进程中可以有多个线程,这些线程都拥有自己的计数器、堆栈、局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,使得我们觉得是同时执行的。调度线程:操作系统会分出一个个时间片,线程会分配到若干时间片,当线程的时间片用完了就会发生线程调度,并等待着下一次分配。线程优先级就是决定线程或多或少分配一些处理器资源的线程属性。public class Priority { private static volatile boolean no原创 2020-11-07 21:24:06 · 170 阅读 · 0 评论 -
java初始化一个类的处理过程
第一阶段通过在Class对象上同步(即获取class对象上的锁),来控制类或者接口的初始化,这个获取锁的线程会一直等待,知道当前线程获取到这个初始化锁。假设Class对象当前没有被初始化,(初始状态为state,标记state =noInitialzation),且有两个线程AB同时试图初始化这个对象第二阶段线程A执行类的初始化,同时B在初始化锁的condition上等待第三阶段,A设置state=initialized,然后唤醒在condition中等待的所有线程B结束类的初始化处理.原创 2020-11-07 15:27:40 · 176 阅读 · 0 评论 -
java并发编程的艺术--锁的内存语义、双重检查锁定
由于volatile仅仅保证单个volatile变量的读/写变量读/写具有原子性,而锁的互斥性的特性可以确保对转增个临界区代码的执行具有原子性。 int a = 0; public synchronized void writer() { //1 a++;//2 } //3 public synchronized void reader() { //4 int i = a; //5 //.... } //6根据程原创 2020-11-07 00:21:22 · 132 阅读 · 0 评论 -
volatile内存语义的实现
为了实现volatile的内存语义,编译器在生成字节码时,会把指令序列中插入内存屏障来禁止特定类型的处理器重排序。下面是基于保守策略的JMM内存屏障插入策略在每个volatile写操作前面插入一个StoreStore屏障在每个Volatile写操作后面插进入一个StoreLoad屏障在每个volatile读操作的后面插入一个LoadLoad屏障在每个volatile读操作的后面插入LoadStore屏障...原创 2020-11-06 23:13:13 · 181 阅读 · 0 评论 -
java并发编程的艺术-volatile的内存语义
//使用volatile声明64位的long变量 volatile long v1 = 0L; //单个volatile的写 public void set(long l) { v1 = 1; } //多个volatile的读写 public void getAndIncrement() { v1++; } //单个volatile的读 public long get() { r..原创 2020-11-06 00:09:57 · 216 阅读 · 5 评论 -
java并发编程的艺术-Java内存模型
线程之间的通信机制:共享内存和消息传递在共享内存的并发模型中,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信。在消息传递的并发模型中,线程之间没有公共状态,线程之间必须通过发送消息来显式进行通信。JAVA采用共享内存的并发模型java中,所有实例域、静态域、数组元素都存储在堆内存中,堆内存在线程之间共享。java线程之间的通信又java内存模型(JMM)控制,JMM决定了一个线程对共享变量的写入何时对另一个线程可见。线程之间的共享变量存储在主内存中,每个线程都有一个私有的原创 2020-11-04 23:39:45 · 145 阅读 · 0 评论 -
Java并发编程的艺术-轻量级锁+原子操作的实现原理
轻量级锁加锁:线程在执行同步块的时,JVM会先在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头中的MarkWord复制到锁记录中,然后线程尝试使用CAS将对象头中的MarkWord替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,标识其他线程争夺锁。当前线程则尝试使用自旋来获取锁。轻量级锁解锁解锁时,会使用CAS将锁记录替换回到对象头,如果成功,说明没有竞争发生,如果失败,说明存在竞争,锁就会膨胀为重量级锁。...原创 2020-11-03 00:35:18 · 149 阅读 · 0 评论 -
java并发编程的艺术-学习笔记(2)
java并发机制的底层实现原理java代码在编译后会变成java字节码,字节码被类加载器加载到JVM中,JVM执行字节码最终需要转换为汇编指令在cpu上运行,并发机制依赖于JVM的实现和cpu指令volatilevolatile是轻量级的synchronized,他在多任务处理中保证了共享变量的可见性。可见性就是当一个线程修改一个共享变量的时候,另一个线程能够读到这个变量的值。volatile不会引起线程上下文的切换和调度。定义: java容许线程访问共享变量,为了确保共享变量能被准确和一致的更新原创 2020-11-01 20:51:13 · 91 阅读 · 0 评论 -
java并发编程的艺术-学习笔记(1)
第一章-并发编程的挑战上下文切换CPU通过时间片算法来循环执行任务,当前任务执行一个时间片会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便于下次切换回这个任务时,可以再次加载这个任务的状态。从任务的保存到在加载就是一次上下文切换CPU是通过给每个线程分配cpu时间片来实现多线程的,时间片特别短,一般为几十毫秒,cpu通过不同的切换线程,让我们感觉到多线程是同时工作的。如何减少上下文切换无所并发编程:多线程竞争锁,会引起上下文切换, 所以要避免使用锁CAS算法:Java中的Atom原创 2020-11-01 16:58:19 · 89 阅读 · 0 评论