![](https://img-blog.csdnimg.cn/20190927151101105.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
并发编程
文章平均质量分 60
并发编程
码拉松
这个作者很懒,什么都没留下…
展开
-
【Java并发工具类】Future介绍
Future是一个接口类,定义了5个方法:通过这5个方法可以看出,Future不但可以获取提交任务的执行结果,甚至还可以取消任务。摘自JDK中Future示例代码注意:方法是阻塞式的,如果调用该方法的时候任务尚未执行完成,则会一直等待下去,直到任务执行结束。ExecutorService还有一个sumbit方法比较特殊:这个方法可以先把result这个参数传给task使用,然后再通过get方法把result返回。FutureTaskFutureTask是一个实现了Runnable和Future接口的原创 2022-06-03 11:30:50 · 459 阅读 · 0 评论 -
【Java并发编程常见错误】多个资源共享的保护
文章目录1. 业务场景2. 问题分析3. 注意锁的对象1. 业务场景简单模拟一个A账户像B账户转账的场景,A账户减少1元,B账户就增加1元。代码实现如下,为了演示多线程共享资源竞争的问题,使用CountDownLatch模拟并发。public class Test_01 { public static final CountDownLatch start = new CountDownLatch(1); public static final CountDownLatch done原创 2022-05-02 21:49:16 · 795 阅读 · 0 评论 -
【Java并发工具类】Semaphore适用场景介绍
前言Semaphore是一种计数信号量,利用它可以控制一定数量的请求,从而实现资源访问限制的目的,实际应用中,可以用来限制访问某种资源的数量,比如在Hystrix中就有基于Semaphore的资源隔离策略。...原创 2022-04-07 23:03:19 · 1944 阅读 · 0 评论 -
【Java并发工具类】CyclicBarrier适用场景介绍
前言前面介绍了CountDownLatch的适用场景,本文将继续来看看另一种与CountDownLatch类似的线程同步工具:CyclicBarrier。CyclicBarrier与CountDownLatch最主要的区别就在于,CyclicBarrier的等待是可以循环的,等待完之后还可以重新适用。并行计算我们将上一遍中通过CountDownLatch实现的并行计算改为由CyclicBarrier实现,并且利用CyclicBarrier的特性,实现重复三次计算过程。public class Cy原创 2022-03-22 21:04:03 · 1013 阅读 · 0 评论 -
【Java并发工具类】CountDownLatch适用场景介绍
CountDownLatch基本介绍主要用途原创 2022-03-21 09:30:00 · 1590 阅读 · 0 评论 -
ConcurrentHashMap与HashMap性能对比
ConcurrentHashMap与HashMap对比原创 2022-02-12 10:31:22 · 3164 阅读 · 0 评论 -
ThreadLocal使用不当引发的问题
实际场景中使用ThreadLocal时的注意点原创 2022-02-09 08:34:51 · 936 阅读 · 0 评论 -
从同步编程到异步编程的过程
前言我们都知道要想提高系统的吞吐量,就一定离不开异步编程的思想,无论是平时项目中接触到的MQ、响应式编程还是操作系统里的AIO、epoll本质上都是在利用异步的方式,提升系统的并行度,本文通过一个简单的小案例来看看如何利用Java中的Futrue完成从同步到异步的转变。场景介绍我们举一个简单的小场景,用户购物,假设就分为三步:1、查看库存是否充足 2、下单支付 3、扣减库存...原创 2021-08-31 19:37:52 · 356 阅读 · 0 评论 -
线程安全集合的几种方式、性能对比、适用场景分析
Set的底层实际上就是Map,所以线程安全的Set一般都会在Map上做文章,本文介绍的主要是JDK自带的一些方式。测试方法没有使用任何专业的测试工具,直接用代码创建线程来模拟,所以为了确保数据相对准确,每种方法都测试了20组。测试代码import java.util.Collections;import java.util.Iterator;import java.util.Set;import java.util.UUID;import java.util.concurrent.Concu原创 2020-11-09 16:47:24 · 1493 阅读 · 0 评论 -
ArrayBlockingQueue中几种添加和取出元素方法的解析
public class TestBlockingQueue { public static void main(String[] args) { testAdd(); System.out.println("=====================我是分隔符========================="); testOffer(); System.out.println("=====================我是分原创 2020-11-09 11:39:58 · 1043 阅读 · 0 评论 -
Java多线程经典的4道笔试题---含多种实现方式
1、按序输出同时启动三个线程,分别为A、B、C,其中A线程打印“a”,B线程打印“b”,C线程打印“c”,要求按照abc顺序打印输出。第一种方式使用join实现,join方法表示调用线程必须等待该线程执行完成后才能继续往下执行。public class SortPrint { public static void main(String[] args) throws InterruptedException { SortPrint sortPrint = new SortP原创 2020-11-07 21:08:10 · 3159 阅读 · 2 评论 -
AbstractQueuedSynchronizer公平锁与非公平锁的实现
首先关于AbstractQueuedSynchronizer就不过多介绍了,在之前的文章中已经详细的介绍过了先关部分,不熟悉的同学建议先看之前的文章中的内容。分析AbstractQueuedSynchronizer(AQS)使用并实现自定义锁基于AbstractQueuedSynchronizer实现锁的源码分析基本使用ReentrantLock默认情况下是非公平锁,另外还提供了一个带boolean类型的构造方法,传入true,就表示要使用公平锁。 /** * Creates an原创 2020-11-06 13:11:49 · 255 阅读 · 0 评论 -
并发编程中生产者与消费者几种实现方式
wait、notifypublic class ProducerAndConsumer { public static void main(String[] args) { GoodsFactory goodsFactory = new GoodsFactory(); new Producer(goodsFactory).start(); new Consumer(goodsFactory).start(); }}class Produ原创 2020-08-19 09:47:07 · 381 阅读 · 0 评论 -
实际项目中如何更好的利用多线程
多线程对于大家来说都不陌生,简单的来说就是在一个进程运行时产生了多个线程,以此来同步完成多项任务,注意多线程不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。本文不会过多的解释关于多线程的一些基础概念,重点将关注如何在实际项目中更好的使用多线程,因为我相信可能有很多项目中可能并不需要我们使用多线程,或者说开发人员并没有注意到可以使用多线程,其次多线程也并不是创建的越多越好,再加上共享资源下线程安全,死锁等问题,这就使得我们在使用多线程时可能总是畏原创 2020-07-31 14:42:22 · 3006 阅读 · 1 评论 -
基于AbstractQueuedSynchronizer实现锁的源码分析
定义AbstractQueuedSynchronizer为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁定和相关同步器(ReentrantLock、Semaphore,CountDownLatch等等)提供一个框架。此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。但只是为了获得同步而只追踪使用 getState()、set原创 2020-07-12 21:07:51 · 1435 阅读 · 0 评论 -
分析AbstractQueuedSynchronizer(AQS)使用并实现自定义锁
AbstractQueuedSynchronizer为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁定和相关同步器(ReentrantLock、Semaphore,CountDownLatch等等)提供一个框架。此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。但只是为了获得同步而只追踪使用 getState()、setSta原创 2020-07-10 11:22:34 · 1470 阅读 · 0 评论 -
理解死锁产生的四个必要条件
死锁的定义死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。死锁产生的四个必要条件1、互斥条件:线程对已经获取到的资源进行排他性使用,即该资源同时只有一个线程占用,如果此时还有其他线程请求获取该资源,则必须等待,直到占用资源的线程释放。2、请求并持有条件:一个线程已经持有了至少一个资源,但又请求了新的资源,而新的资源已经被其他线程占用,所以当前原创 2020-07-05 22:25:47 · 7836 阅读 · 0 评论 -
乐观锁与悲观锁的比较与应用场景
乐观锁和悲观锁的思想?乐观锁就是认为每次线程对数据的访问并不存在冲突,没有别的线程去修改这个数据,因此并不会通过锁来控制线程之间对数据的竞争问题,而是在最终更新数据时确认一下数据没有被更新。悲观锁是认为每次对数据的访问都存在冲突,每次都同时有多个线程在修改数据,因此当有一个线程对数据访问时必须通过上锁来阻塞其他线程对数据的访问。两种方式的使用场景根据两种锁的思想分析来看,一般认为乐观锁比较适用于冲突较少的场景,也就是读多写少的情况,对于数据的访问多数是读的访问,这样就可以通过乐观锁的方式省去了加锁、原创 2020-07-04 22:01:26 · 3552 阅读 · 0 评论 -
JDK1.6对synchronized锁的优化
在JDK1.6之前synchronized关键属于一种重量级的锁,性能能略显不足,从JDK1.6开始对synchronized做了一些优化,感觉主要就是针对到底要不要加锁,加什么锁做了一些判断,下面一起来看一下吧。1、锁消除最大程度的优化就是没有锁,那么如何判断能不能消除synchronized呢?在编译期间有一种优化叫做逃逸分析。如果证明一个对象不会逃逸到方法外或者线程外,则可针对此变量进行优化,JVM判断对象是否逃逸的依据有:1、对象被赋值给堆中对象的字段和类的静态变量。2、对象被传进了不确定原创 2020-07-03 15:30:56 · 2220 阅读 · 1 评论 -
线程的生命周期及各状态扭转说明
线程的生命周期图原创 2020-07-01 19:00:46 · 2498 阅读 · 0 评论 -
synchronized和lock区别对照表
sync和lock的区别原创 2020-07-01 11:05:03 · 2350 阅读 · 0 评论 -
Volatile关键字特性详解
volatile是一种轻量级的同步机制,不会引起的线程上下文切换,可以保证可见性和禁止重排序,但不能保证原子性带来的线程安全问题。volatile特性可见性当有多个线程访问同一个变量时,一个线程对此变量的修改,其他线程应该立刻可获取到修改后的值。一个变量用volatile修饰后,当对此变量写入时,会立刻将写入后的值刷新到主存中,并且将其他线程本地内存中保存的值失效,其他线程读取此变量时,会直接从主内存中读取。public class VolatileDemo { private stati原创 2020-06-28 19:59:27 · 3781 阅读 · 0 评论 -
CountDownLatch、Semaphore、CyclicBarrier应用与解析
CountDownLatchCountDownLatch能够实现让某一个线程等待其他线程执行完成后再执行,比如多个线程负责计算各自的数据,数据之间没有联系,一个线程等待所有线程都计算完后进行数据的汇总。传统的串行执行的方式,假设线程A/B/C分别进行计算,再由D线程汇总数据,总共耗时7秒。但是如果A/B/C计算之间并没有任何依赖关系,那么就可以让他们同时进行计算,线程D等待所有线程都执行完之后再进行汇总,这样总共耗时就只需4秒。当然除了CountDownLatch,还有其他的一些方法也能实现类似的效原创 2020-06-26 20:35:40 · 2265 阅读 · 0 评论 -
JDK提供的线程池详解
为什么要使用线程池?减少不必要的资源消耗,将线程交由线程池管理,可以有效的避免线程的频繁创建与销毁。可以有效的对线程的数量进行控制,避免创建过多的线程导致系统资源被大量消耗,反而降低系统的响应时间。JDK中线程池的核心参数定义corePoolSize核心线程数,即线程池始终保持着corePoolSize个线程数。maximumPoolSize线程池中最多允许创建maximumPoolSize个线程。keepAliveTime假设corePoolSize是5,maximumPoolSiz原创 2020-06-22 14:40:29 · 2079 阅读 · 0 评论 -
wait和sleep使用的区别和注意
原创 2020-06-19 13:55:37 · 2040 阅读 · 0 评论 -
sonar对于处理InterruptedException异常提示的原因分析
当我们使用会抛出InterruptedException异常的方法时,如果处理不当可能会发生一些预期之外的问题。下面看一段代码演示:public class ThreadInterruptedDemo { public static void main(String[] args) throws InterruptedException { Thread myThread = new MyThread(); myThread.setName("my thread原创 2020-06-18 17:18:36 · 5208 阅读 · 0 评论 -
ThreadLocal存储结构及内存溢出问题分析
ThreadLocal是为了解决多线程并发访问共享变量时造成数据异常的问题,与加锁的思想方式不同,ThreadLocal是通过为每个线程提供一个变量的副本,以此保证并发访问的安全。先看一下在没有使用ThreadLocal的情况下对于共享变量的访问结果:/** * 启动两个线程,各执行100次对共享变量count加1,得到的结果可能并不是200,而是一个无法确定的数 */public class NoUseThreadLocal { static int count = 0; pu原创 2020-06-17 22:29:46 · 2899 阅读 · 0 评论