juc

【JUC】JDK1.8源码分析之ReentrantLock(三)

你。 提交于 2020-03-20 03:44:15
一、前言   在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看ArrayBlockingQueue源码会很容易,下面开始正文。 二、ArrayBlockingQueue数据结构   通过源码分析,并且可以对比ArrayList可知,ArrayBlockingQueue的底层数据结构是数组,数据结构如下   说明:ArrayBlockingQueue底层采用数据才存放数据,对数组的访问添加了锁的机制,使其能够支持多线程并发。 三、ArrayBlockingQueue源码分析    3.1 类的继承关系    public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {}   说明:可以看到ArrayBlockingQueue继承了AbstractQueue抽象类,AbstractQueue定义了对队列的基本操作;同时实现了BlockingQueue接口,BlockingQueue表示阻塞型的队列,其对队列的操作可能会抛出异常;同时也实现了Searializable接口,表示可以被序列化。   

JUC并发Atomic原子类介绍

ⅰ亾dé卋堺 提交于 2020-03-10 05:07:55
1 Atomic 原子类介绍 Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。 所以,所谓原子类说简单点就是具有原子/原子操作特征的类。 并发包 java.util.concurrent 的原子类都存放在 java.util.concurrent.atomic 下,如下图所示。 根据操作的数据类型,可以将JUC包中的原子类分为4类 基本类型 使用原子的方式更新基本类型 AtomicInteger:整型原子类 AtomicLong:长整型原子类 AtomicBoolean :布尔型原子类 数组类型 使用原子的方式更新数组里的某个元素 AtomicIntegerArray:整型数组原子类 AtomicLongArray:长整型数组原子类 AtomicReferenceArray :引用类型数组原子类 引用类型 AtomicReference:引用类型原子类 AtomicReferenceFieldUpdater:原子更新引用类型里的字段 AtomicMarkableReference :原子更新带有标记位的引用类型 对象的属性修改类型 AtomicIntegerFieldUpdater

JUC -多线程锁问题:

懵懂的女人 提交于 2020-03-09 06:25:24
多线程锁问题: 8锁现象下名词解释: 顺序执行:先调用的先执行 随机执行:没有规律,与计算机硬件资源有关,哪个线程先得到资源就先执行,各个线程之间互不干扰。 多个线程使用同一把锁- 顺序执行 多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行! public class MultiThreadUseOneLock01 { public static void main ( String [ ] args ) { Mobile mobile = new Mobile ( ) ; // 两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行! new Thread ( ( ) - > mobile . sendEmail ( ) , "A" ) . start ( ) ; // 干扰 try { TimeUnit . SECONDS . sleep ( 1 ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } new Thread ( ( ) - > mobile . sendMS ( ) , "B" ) . start ( ) ; } } // 手机,发短信,发邮件 class Mobile { // 被 synchronized 修饰的方法、锁的对象是方法的调用者、 public

Java多线程系列--“JUC原子类”02之 AtomicLong原子类

耗尽温柔 提交于 2020-03-09 05:38:33
什么是线程安全? 当多个线程访问某个类时,不管这些的线程的执行顺序如何,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。 哈哈书上的解释,还是翻译过来的,看了半天还是觉得有点奇怪。比如说 “类都能表现出正确的行为” 是毛线意思?在网上搜了一番 "线程安全就是说多线程访问同一代码,不会产生不确定的结果" 这样反而跟容易理解,果然读书要么读原版中文书要么读原版英文书,看英文的翻译版真的是蛋疼无比。说到这里,我以前貌似把多线程及线程安全一个根本性问题搞混淆了: 所谓的多线程是指多个线程跑同一段代码,所以线程安全的概念是针对于这段代码而言的而不是针对线程。 一个 无状态 的Servlet //程序清单2-1 一个无状态的Servelet @ThreadSafe public class StatelessFactorizer implements Servlet{ public void service(ServlerRequest req, ServletResponse resp){ BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); encodeIntoResponse(resp, factors); } }

JUC - Synchronized 和 Lock 的区别

最后都变了- 提交于 2020-03-08 22:07:15
JUC - Synchronized 和 Lock 的区别 面试题:Synchronized 和 Lock 有什么区别? 用新的 Lock 有什么好处?你举例说说。 1,原始构成 synchronized 是关键字属于JVM层面, monitorenter 底层是通过 monitorenter 对象来完成,其实 wait/notify 等方法也依赖于 monitor 对象只有在同步块或方法中才能调 wait/notify 等方法 monitorexit 退出,下图中有两个 monitorexit,第一个是正常退出,第二个是即使报错了也可以退出。 Lock 是具体的类(java.util.concurrent.locks.lock) 是 api 层面的锁 2,使用方法 synchronized 不需要用户去手动释放锁,当 synchronized 代码块执行完后系统会自动让线程释放对锁的占用 ReentractLock 需要用户去手动释放锁,若没有主动释放锁,就有可能导致出现死锁现象。 需要lock() 和 unLock() 方法配合 try/finally 语句块来完成 3,等待是否可中断 synchronized 不可中断,除非抛出异常或者正常运行完成 ReenterantLock 可中断: 1,设置超时方法 tryLock(long timeout,TimeUnit unit)

JUC知识点汇总

左心房为你撑大大i 提交于 2020-03-08 20:55:57
JUC汇总 总结: 总结: 通常说的并发包即java.util.concurrent及其子包,集中了Java并发的各种基础工具类,具体: 提供了比Synchronized更高级的各种同步结构:CountDownLatch、CyclicBarrier、Semaphore等,可实现更丰富的多线程操作,例如用Semaphore作为资源控制器,限制同时工作的线程数量。 JUC之各种同步结构(Semaphore、CountDownLatch、CyclicBarrier) 各种线程安全容器:ConcurrentHashMap、有序的ConcurrentSkipListMap或通过快照机制,实现线程安全的动态数组CopyOnWriteArrayList JUC之各种线程安全容器 各种并发队列,各种BlockedQueue实现,如ArrayBlockingQueue、SynchronousQueue,或针对塔顶场景的PriorityBlockingQueue等 JUC 之各种并发队列Concurrent、CopyOnWrite、Blocking 强大的Executor框架,可创建不同类型的线程池,绝大部分情况下不需要自己从头实现线程池和任务调度器 JUC之各种线程池 补充知识点: Unsafe机制补充 并发包内部组成AQS 和 CAS 来源: CSDN 作者: 来柯 链接: https:/

[JUC第一天]浅谈volatile关键字

馋奶兔 提交于 2020-03-08 10:09:38
文章目录 概述 可见性 为什么有时会不可见 如何解决 防止重排序 一个有趣的例子 重排序会导致什么 内存屏障 原子性 什么是原子性 volatile变量不具有原子性 概述 在Java语言规范第三版中, volatile 关键词的定义如下: Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地使用和更新,线程应该确保通过排他锁单独获得这个变量 并发编程中有两个很常见的关键词: synchronized 和 volatile volatile 可以用来修饰一个变量,使得并发情况下所有线程得到这个对象的值都是一样的 相比与 synchronized 操作会找个东西当锁, volatile 则是通过实时共享变量的值的方式来保证变量的可见性的,而并没有锁什么东西,所以说他的使用并不会引起程序的上下文切换,所以也说,volatile是轻量级的synchronized volatile最大的两个特点就是: 使得内存模型中所有线程获取到的值都是统一的(可见性) 避免指令在执行的时候因为优化机制重排序而出错 可见性 内存可见性 :每一个工作线程看到的某个变量的值都是相同的,而且是他最新的状态 为什么有时会不可见 这首先就要从计算机的缓存说起了: 很久以前,计算机的CPU和内存是直接连着的,但是这样导致的是传输速度跟不上CPU的运算速度 后来的计算机中通过设置缓存的方式

使用Redis单实例实现分布式锁

自古美人都是妖i 提交于 2020-03-08 06:33:59
为什么使用redis分布式锁 在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候,juc包的锁就无能无力了,这时候就需要分布式锁了。常见的有使用zk的最小版本,redis的set函数,数据库锁来实现。 使用分布式锁 package com.jiaduo.DistributedLock; import java.util.Collections; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class DistributedLock { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; private static final Long RELEASE_SUCCESS = 1L; private static void validParam(JedisPool jedisPool, String

JUC并发编程(五):快速了解线程池

时光毁灭记忆、已成空白 提交于 2020-03-07 18:43:33
池化技术 首先我们要了解的一个东西就是程序运行的本质是占用系统资源! 所以我们为了提高程序的使用效率,降低我们的一个性能消耗,就要把一些频繁创建的资源提前给准备好,这就是池化技术. 常见的有线程池,连接池,内存池,对象池… 其次我们为什么要用线程池-- 多路复用 关于线程池,我们只要掌握三大方法,七大参数,四种拒绝策略即可!下 三大方法 newFixedThreadPool(),newCachedThreadPool(),newSingleThreadExecutor() public class Test1 { public static void main ( String [ ] args ) { //线程池 Executors原生三大方法 //固定大小 ExecutorService threadpool1 = Executors . newFixedThreadPool ( 5 ) ; //弹性收缩 ExecutorService threadpool2 = Executors . newCachedThreadPool ( ) ; //只有一个 ExecutorService threadpool3 = Executors . newSingleThreadExecutor ( ) ; try { for ( int i = 1 ; i <= 10 ; i ++ ) {

JUC-八锁现象和不安全锁

天大地大妈咪最大 提交于 2020-03-06 20:54:41
1,被 synchronized 修饰的方法,锁的对象是方法的调用者(实例对象) 2,被 static 修饰的方法,锁的对象就是 Class模板对象,这个则全局唯一 问题7: 一个普通同步方法,一个静态同步方法,只有一个手机,请问先执行sendEmail 还是 sendSMS public class LockDemo07 { public static void main(String[] args) throws InterruptedException { Phone7 phone = new Phone7(); new Thread(() -> { try { phone.sendEmail(); } catch (InterruptedException e) { e.printStackTrace(); } }, "A").start(); TimeUnit.SECONDS.sleep(1); new Thread(() -> { phone.sendSMS(); }, "B").start(); } } class Phone7 { public static synchronized void sendEmail() throws InterruptedException { TimeUnit.SECONDS.sleep(3); System.out.println