多线程
文章平均质量分 76
入门小站
这个作者很懒,什么都没留下…
展开
-
Java高并发之CountDownLatch源码分析
概述CountDownLatch 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。简单来说,就是 CountDownLatch 内部维护了一个计数器,每个线程完成自己的操作之后都会将计数器减一,然后会在计数器的值变为 0 之前一直阻塞,直到计数器的值变为 0.简单使用这个例子主要演示了,如何利用 CountDownLatch 去协调多个线程同时开始运行。这个时候的 CountDownLatch 中的计数器的现实含义是等待创建的线程个数,每个线程在开始任务之前都会调用 awai原创 2021-01-30 22:51:02 · 158 阅读 · 0 评论 -
Java并发编程之CAS和AQS
什么是CASCAS(compare and swap),字面意思比较并交换,是解决多线程并行情况下使用锁造成性能损耗的一种机制.public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}CAS有三个操作数,valueOffset内存值,expect期望值,update要更新的值。原创 2021-01-28 22:51:51 · 382 阅读 · 0 评论 -
Java线程池ExecutorService中重要的方法
ExecutorService 介绍ExecutorService是java线程池定义的一个接口,它在java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法。Java API对ExecutorService接口实现有两个,所以这两个即是线程池的具体实现。1. ThreadPoolExecutor2. ScheduledThreadPoolExecutorExecutorService还继承了Executor接口。实线表示继承,需要表示实现原创 2021-01-26 22:42:55 · 632 阅读 · 0 评论 -
Java线程池ThreadPoolExecutor源码分析
继承关系Executor接口public interface Executor { void execute(Runnable command);}ExecutorService接口public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean原创 2021-01-25 22:31:16 · 203 阅读 · 0 评论 -
Java并发线程之线程池
初始化线程池后,把任务丢进去,等待调度就可以了,使用起来比较方便。JAVA中Thread是线程类,不建议直接使用Thread执行任务,在并发数量比较多的情况下,每个线程都是执行一个很短的时间就任务结束了,这样频繁创建线程会大大降低系统的效率,因为频繁的创建和销毁线程需要时间。而线程池可以复用,就是执行完一个任务,并不销毁,而是可以继续执行其它任务。Thread的弊端每次new Thread() 创建对象,性能差。线程缺乏统一管理,可能无限制创建线程,相互竞争,有可能占用过多系统资源导致死机或O.原创 2021-01-24 20:33:58 · 135 阅读 · 0 评论 -
Java高并发BlockingQueue重要的实现类二
DelayQueueDelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed元素。存放到DelayDeque的元素必须继承Delayed接口。Delayed接口使对象成为延迟对象,它使存放在DelayQueue类中的对象具有了激活日期,该接口强制执行下列两个方法:CompareTo(Delayed o):Delayed接口继承了Comparable接口,因此有了这个方法getDelay(TimeUnit unit):这个方法原创 2021-01-23 21:37:46 · 126 阅读 · 0 评论 -
Java高并发BlockingQueue重要的实现类
ArrayBlockingQueue有界的阻塞队列,内部是一个数组,有边界的意思是:容量是有限的,必须进行初始化,指定它的容量大小,以先进先出的方式存储数据,最新插入的在对尾,最先移除的对象在头部。public class ArrayBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable { /** 队列元素 */ fin原创 2021-01-22 23:31:50 · 158 阅读 · 0 评论 -
Java高并发之BlockingQueue
简介多线程中通过队列很容易共享数据,比如经典的生产者和消费者模型中,通过队列可以很方便的实现数据共享。假设我们有若干生产者线程,又有若干消费者线程,生产者线程可以通过队列将数据共享给消费者。但是生产者和消费者在某个时间段内,万一发生数据处理速度不匹配的情况呢?如果生产者生产数据的速度远大于消费者消费数据的速度,理想情况下是当生产者产生的数据到达一个阈值之后,那么生产者必须暂停一下(阻塞生产者线程),以便消费者可以把数据消费掉。在concurrent包出现之前,开发人员必须手动控制这些细节,导致开发高性能原创 2021-01-21 22:25:47 · 252 阅读 · 0 评论 -
Java中J.U.C扩展组件之ForkJoinTask和ForkJoinPool
Fork/Join框架中两个核心类ForkJoinTask与ForkJoinPool,声明ForkJoinTask后,将其加入ForkJoinPool中,并返回一个Future对象。ForkJoinPool:ForkJoinTask需要通过ForkJoinPool来执行,任务分割的子任务会添加到当前工作维护的双端队列中,进入队列的头部。当一个工作线程的队列里暂时没有任务时,它会随机从其它工作线程的队列尾部获取一个任务。ForkJoinTask:我们需要使用ForkJoin框架,首先要创建一个.原创 2021-01-20 21:41:34 · 210 阅读 · 0 评论 -
Java中J.U.C扩展组件之Fork,join
Fork/join介绍Fork/join框架是java7提供的并行执行任务的框架,是把大任务分割成若干小任务,最后汇总若干小任务的执行结果得到最终的结果。它的思想与MapReduce类似。Fork把一个大任务分割成若干小任务,Join用于合并小任务的结果,最后得到大框架的结果。主要采取工作窃取算法。工作窃取(work-stealing)算法是指某个线程从其它队列窃取任务执行。假如我们需要做一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务原创 2021-01-19 23:20:13 · 187 阅读 · 0 评论 -
Java同步组件之Condition,FutureTask
Java同步组件概况CountDownLatch : 是闭锁,通过一个计数来保证线程是否一直阻塞Semaphore: 控制同一时间,并发线程数量CyclicBarrier:字面意思是回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。ReentrantLock:是一个重入锁,一个线程获得了锁之后仍然可以反复加锁,不会出现自己阻塞自己的情况。Condition:配合ReentrantLock,实现等待/通知模型FutureTask:FutureTask实现了接口Future,同F原创 2021-01-18 23:34:44 · 186 阅读 · 0 评论 -
Java同步组件之CyclicBarrier,ReentrantLock
文章目录Java同步组件概况`CyclicBarrier`介绍与`CountDownLatch`比较相同点不同点`CountDownLatch`和`CyclicBarrier`的场景比较代码演示`ReentrantLock`可重入锁`ReentrantLock`(可重入锁)和`synchronized`的区别`ReentrantLock`与`synchronized`的功能区别`ReentrantLock`特有功能`synchronized`的使用场景代码演示`ReentrantLock`常用方法`Reen原创 2021-01-16 21:12:51 · 217 阅读 · 0 评论 -
Java同步组件之CountDownLatch,Semaphore
Java同步组件概况CountDownLatch : 是闭锁,通过一个计数来保证线程是否一直阻塞Semaphore: 控制同一时间,并发线程数量CyclicBarrier:字面意思是回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。ReentrantLock:是一个重入锁,一个线程获得了锁之后仍然可以反复加锁,不会出现自己阻塞自己的情况。Condition:配合ReentrantLock,实现等待/通知模型FutureTask:FutureTask实现了接口Future,同F原创 2021-01-15 22:21:15 · 245 阅读 · 0 评论 -
AQS同步队列结构分析
同步队列结构AQS使用的同步队列是基于一种CLH锁算法来实现。CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋.同步器中包含了两个节点类型的引用,一个指向头节点(head),一个指向尾节点(tail),没有获取到锁的线程,加入到队列的过程必须保证线程安全,因此同步器提供了一个基于CAS的设置尾节点的方法CompareAndSetTail(Node expect,Node update),它需要传递当前线原创 2021-01-13 22:58:31 · 245 阅读 · 0 评论 -
Java并发J.U.C 之 AQS
J.U.C 之 AQSAbStractQueuedSynchronizer类,简称AQS,是一个来构建锁和同步器的框架,JDK1.5开始引入了J.U.C,大大提高了JAVA程序的并发性,而AQS则是J.U.C的核心,是并发类中的核心部分,他是一个基于FIFO队列,这个队列可以构建锁或其它相关的同步基础框架AQS底层结构底层采用双向链表,是队列的一种实现,因此可以当做是一个队列。其中Sync queue即同步队列,它是双向链表,包括hean结点(主要用作后续的调度)与tail结点。Conditi原创 2021-01-11 22:47:24 · 104 阅读 · 0 评论 -
Java并发容器J.U.C
J.U.C是java.util.concurrent的简写,里面提供了很多线程安全的集合。CopyOnWriteArrayList介绍CopyOnWriteArrayList相比于ArrayList是线程安全的,字面意思是写操作时复制。CopyOnWriteArrayList使用写操作时复制技术,当有新元素需要加入时,先从原数组拷贝一份出来。然后在新数组里面加锁添加,添加之后,将原来数组的引用指向新数组。 public boolean add(E e) { final Reen.原创 2021-01-10 19:39:32 · 288 阅读 · 0 评论 -
Java同步容器
ArrayList,HashSet,HashMap都是线程非安全的,在多线程环境下,会导致线程安全问题,所以在使用的时候需要进行同步,这无疑增加了程序开发的难度。所以JAVA提供了同步容器。同步容器ArrayList ===> Vector,StackHashMap ===> HashTable(key,value都不能为空)Collections.synchronizedXXX(List,Set,Map)Vector实现List接口,底层和ArrayList类似,但是Vect.原创 2021-01-09 21:03:02 · 185 阅读 · 0 评论 -
JAVA日期安全格式化之SimpleDateFormat和jodaTime,DateTimeFormatter
SimpleDateFormat线程不安全的日期格式化库SimpleDateFormat是JAVA提供的一个日期转换类。package com.rumenz.task;import java.text.SimpleDateFormat;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;imp原创 2021-01-07 20:02:54 · 251 阅读 · 0 评论 -
StringBuilder与StringBuffer
StringBuilderpackage com.keytech.task;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;//线程不安全public class StringExample1 { publ原创 2021-01-06 23:19:39 · 99 阅读 · 0 评论 -
Java线程封闭
把对象封装到一个线程里,只有一个线程可以看到该对象,那么就算这个对象不是线程安全的,也不会出现任何线程问题,因为它只能在一个线程中被访问。Ad-hoc线程封闭:程序控制实现,非常脆弱,最糟糕,忽略。堆栈封闭:简单的说就是局部变量,无并发问题。多线程访问同一个方法时,方法中的局部变量会被拷贝一份到线程栈中。方法的局部变量不是被多线程共享的,不会出现线程安全问题,能用局部变量就不要用全局变量,全局变量容易发生并发问题,注意全局变量不是全局常量。ThreadLocal线程封闭:Java中提供一个Thr.原创 2021-01-05 21:43:45 · 198 阅读 · 0 评论 -
Java线程安全策略
线程安全策略创建后状态不能被修改的对象叫做不可变对象. 不可变的对象天生就是线程安全的. 不可变对象的常量(变量)是在构造函数中创建的,既然它们的状态永远无法被改变,那么它们永远就是线程安全的。不可变对象需要满足的条件对象创建以后其状态就不能修改。对象的所有域都是fina类型。对象是正确创建的(在对象创建期间,this引用没有逸出)并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了finalfinal关键字:类,方原创 2021-01-04 23:08:41 · 153 阅读 · 0 评论 -
Java安全的发布对象
安全发布对象在静态初始化函数中初始化一个对象引用将对象的引用保存到volatile类型域或者AtomicReference对象中将对象的引用保存到某个正确构造对象的final类型域中将对象的引用保存到一个由锁保护的域中Spring 框架中,Spring管理的类都是单例模式。如何保证一个实例只被初始化一次,且线程安全?通过不同单例的写法,具体描述安全发布对象的四种方法:在静态初始化函数中初始化一个对象的引用(不推荐)package com.rumenz.task.single;//原创 2021-01-03 23:33:45 · 156 阅读 · 1 评论 -
Java多线程之有序性
有序性在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响单线程执行的结果,会影响到多线程并发执行结果的正确性volatile,synchronized,Lock通过volatile,synchronized,Lock保证一定的有序性,synchronized,Lock保证每一时刻只有一个线程可以执行同步代码块,相当于让线程顺序执行同步代码,从而保证有序性。另外,JVM具备一些先天的有序性,即不需要额外的手段就能保证有序性,即Happens-before原则,如果两个操原创 2021-01-02 22:23:32 · 557 阅读 · 2 评论 -
多线程之线程可见性synchronized
synchronized的规定线程解锁前,必须把共享变量刷新到主内存线程加锁前将清空工作内存共享变量的值,需要从主存中获取共享变量的值。加锁(synchronized 同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性。我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化。而线程的同步恰恰也能够实现这一点。内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。为了确保原创 2021-01-01 22:27:57 · 161 阅读 · 0 评论 -
Java多线程之可见性之volatile
可见性一个线程对主内存的修改可以及时被其它线程观察到导致共享变量在线程间不可见的原因线程交叉执行指令重排序加上线程交叉执行共享变量更新后的值没有在工作内存与主存间及时更新保证可见性和原子性对于可见性Java提供了synchonized和volatilevolatile通过加入内存屏障和禁止重排序优化来实现,保证可见性不保证原子性对volatile变量进行写操作时,会在写操作后加入一条store屏障指令,将工作内存变量值刷新到主内存。对volatile变量进行读操作时原创 2020-12-31 23:10:35 · 135 阅读 · 0 评论 -
AtomicStampedReference解决CAS的ABA问题
AtomicStampReference解决CAS的ABA问题什么是ABAABA问题:指CAS操作的时候,线程将某个变量值由A修改为B,但是又改回了A,其他线程发现A并未改变,于是CAS将进行值交换操作,实际上该值已经被改变过,这与CAS的核心思想是不符合的ABA解决方案每次变量更新的时候,把变量的版本号进行更新,如果某变量被某个线程修改过,那么版本号一定会递增更新,从而解决ABA问题AtomicReference 演示ABA问题package com.keytech.task;原创 2020-12-30 23:35:18 · 224 阅读 · 0 评论 -
AtomicReference原子性引用
AtomicReferenceAtomicReference类提供了一个可以原子读写的对象引用变量。 原子意味着尝试更改相同AtomicReference的多个线程(例如,使用比较和交换操作)不会使AtomicReference最终达到不一致的状态。 AtomicReference甚至有一个先进的compareAndSet()方法,它可以将引用与预期值(引用)进行比较,如果它们相等,则在AtomicReference对象内设置一个新的引用。AtomicStampReference 安全的修改一个变量原创 2020-12-29 22:20:00 · 479 阅读 · 0 评论 -
线程安全之原子性Atomic(AtomicInteger|LongAdder|AtomicLong)
线程安全性当多线程访问某个类时,不管运行环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何的同步或者协同,这个类都能表现出正确的行为,那么这个类就是线程安全的.原子性提供互斥访问,同一时刻只有一个线程对它进行访问.Atomic包位于java.util.concurrent.atomic,AtomicXXX : CAS、Unsafe.compareAndSwapXXXCAS(Compare and swap)比较和替换是设计并发算法用的的一项技术,比较和替换是原创 2020-12-28 22:58:44 · 609 阅读 · 0 评论 -
CountDownLatch和Semaphore使用场景
CountDownLatchCountDownLatch位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等到其它3任务完成才能执行,此时就可以用CountDownLatch来实现。假设计数器的值为2,线程A调用await()方法之后,A线程就进入了等待状态,之后其它线程中执行countDown(),计数器就会-1,该操作线程继续执行,当计数器从2编程0,线程A继续执行。package com.keytech.task;import原创 2020-12-26 22:01:54 · 3225 阅读 · 0 评论 -
Java内存模型 - 同步八种操作
Java 内存模型 - 同步操作与规则Java内存模型 - 同步八种操作锁定(lock): 作用于主内存中的变量,将他标记为一个线程独享变量。通常意义上的上锁,就是一个线程正在使用时,其他线程必须等待该线程任务完成才能继续执行自己的任务。解锁(unlock): 作用于主内存中的变量,解除变量的锁定状态,被解除锁定状态的变量才能被其他线程锁定。执行完成后解开锁。read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的 load 动作使用。从主原创 2020-12-25 23:55:10 · 167 阅读 · 0 评论 -
JVM与计算机之间的关系
计算机内存硬件架构CPU,一台现代计算机拥有两个或多个CPU,其中一些CPU还有多核,从这一点可以看出,在一个有两个或多个CPU的现代计算机上,同时运行多个线程是非常有可能的,而且每个CPU在某一个时刻,运行一个线程是肯定没有问题的,这意味着,如果Java程序是多线程的,在Java程序中,每个CPU上一个线程是可能同时并发执行的。CPU Refisters(寄存器),每个CPU都包含一系列的寄存器,它们是CPU内存的基础,CPU在寄存器中执行操作的速度远大于在主存上执行的速度,这是因为CPU访问原创 2020-12-24 23:41:14 · 595 阅读 · 0 评论 -
Java 内存模型(Java Memory Model,JMM)
为了屏蔽各种硬件和操作系统的内存访问差异,JVM制定了一套JMM内存模型来实现同一套Java程序在不同平台上实现一样的运行效果。也就是一次编译到处运行跨平台的效果。JVM内存分配概念JVM两个重要的概念:堆(Heap)和栈(Stack)Java中Heap是运行时数据区,有垃圾收集器负责,它的优势的是动态分配内存,生命周期不必事先告诉编译器,在运行时动态分配内存,JVM垃圾收集器会自动回收不再使用的数据.缺点是:由于是在运行时分配的内存,所以存取速度相对较慢。Java中的Stack比He.原创 2020-12-23 23:18:07 · 156 阅读 · 0 评论