并发编程
文章平均质量分 84
架构师的小跟班
这个小伙好懒,啥都没写
展开
-
synchronized能防止指令重排序吗?
疑问volatile关键字和synchronized关键字。synchronized可以保证原子性、有序性和可见性。而volatile却只能保证有序性和可见性。注意:这两个有序的意思是不一样的。那么,我们再来看一下双重校验锁实现的单例,已经使用了synchronized,为什么还需要volatile?这个volatile是否可以去掉?public class SingleInstance{ // 使用 volatile 禁止 new 对象时进行指令重排 // new 对象,有三转载 2021-03-19 20:12:28 · 2201 阅读 · 1 评论 -
AbstractQueuedSynchronizer(AQS) 的原理简述
简述AQS(抽象同步器) 就是 AbstractQueuedSynchronizer 抽象类的简称,可以通过继承该类快速的实现同步多线程下的同步容器。如:ReadWriteLock、ReentrantLock,或者 CountDownLatch 与 Semaphore,甚至是线程池类 ThreadPoolExecutor 都继承了 AQS。可以一句话概括它的作用,AQS的实现依赖内部的同步队列,也就是FIFO的双向链表,如果当前线程竞争锁失败,那么AQS会把当前线程以及等待状态信息构造成一个No转载 2021-02-20 23:38:13 · 517 阅读 · 0 评论 -
生产者和消费者的三种实现方式(Java)
什么是生产者消费者问题 ?生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题是一个多线程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。注:该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。要解决该问题,就必须让生产者在缓冲区满时休眠(要原创 2021-02-15 17:28:21 · 1692 阅读 · 0 评论 -
真正理解 Java的Thread#join
前言Thread#join() 内部调用了 同步方法 Thread#join(long millis),该方法 由 synchronized 修饰,该方法内部 又调用了 Object#wait(0)注:Object#wait(0) 和 Object#wait() 一样,都是让调用此方法的线程进入永久阻塞,唯一的区别就是,Object#wait(0) 让线程 变为 TIMED_WAITING 状态,而,Object#wait() 则是让线程变为 WAITING 状态。Thread#join(long原创 2021-02-15 16:13:08 · 167 阅读 · 2 评论 -
苦逼的 8 锁逻辑
首先说明,“Java 八锁” 描述的是 八种加锁的逻辑。这里 加锁都依靠 synchronized 关键字。Java的8锁的Demosynchronized 加的锁是啥?注:Java 的任何一个对象 都可以成为锁,包括 Class 对象。同步代码块例如:// 方式一synchronized(Object.class){ //}// 方式二Object lock = new Object();synchronized(lock){ // }以同步代码块的形.原创 2021-02-14 19:04:31 · 151 阅读 · 0 评论 -
使用 notifyAll 和 wait 模拟生产者和消费者的问题
实现此问题之前,有必要先了解一下 Java 描述的"锁"的原理。等待对列和同步队列的简单概述线程A 执行 synchronized(obj) 相当于 JVM会创建 一个 Monitor(监视器) 对象,JVM 将 obj 对象的对象头的 MarkWord 字段 指向 Monitor,同时Monitor 的 Owner指向 线程A,而且 Owner只可以指向一个线程,这就相当于给 obj 对象加好锁了。当前对象 obj 被上了一把锁后,那么,其他线程在执行synchronized(obj)时,由于 ob原创 2021-02-13 01:28:05 · 185 阅读 · 1 评论 -
Java 描述的 synchronized 加“锁“ 到底是啥?
多线程同步的锁(Monitor) 和 Java对象头(Object Header)密切相关Java 对象头在JVM中,对象在内存中的布局分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。HotSpot 虚拟机的对象头(Object Header)包括两部分信息:第一部分,是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的.转载 2021-02-12 23:29:43 · 173 阅读 · 0 评论 -
SimpleDateFormat#parse和format方法的线程安全问题及解决办法
我经常使用SimpleDateFormat类,将日期在String和Date之间做转化。使用SimpleDateFormat#parse方法,可以将满足格式要求的字符串转换成Date对象使用SimpleDateFormat#format方法,可以将Date类型的对象转换成一定格式的字符串同时,我也注意到 SimpleDateFormat 的某些方法 并非是线程安全的,也就是说在并发环境下,如果多个线程共享 SimpleDateFormat 对象(声明为全局变量或者静态全局变量等),就有可能会出现线原创 2021-02-11 22:31:12 · 1212 阅读 · 3 评论 -
ThreadPoolExecutor线程池的keepAliveTime的具体含义
keepAliveTime含义ThreadPoolExecutor 的 javadoc 对 keepAliveTime 参数的解释:keepAliveTime when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.大致意思是:keepAliveTime 就是 当原创 2021-02-11 21:04:45 · 4448 阅读 · 0 评论 -
线程池的状态
线程的状态我们都知道线程的状态 可以分为 创建(NEW)、运行(RUNNABLE)、阻塞(BLOCK)、等待(WAITING/TIMED-WAITING)和结束(TERMINATED)线程池状态线程是线程池的一部分,线程的状态和线程数量决定着线程池的状态,Java把线程池的状态分为五种:运行(RUNNING):该状态下的线程池接收新任务并处理队列中的任务;线程池创建完毕就处于该状态,也就是正常状态;关机(SHUTDOWN):线程池不接受新任务,但处理队列中的任务;线程池调用shutdown()之原创 2021-02-02 20:21:46 · 273 阅读 · 0 评论