多线程
文章平均质量分 92
Erica_1230
这个作者很懒,什么都没留下…
展开
-
ReentrantLock源码分析
ReentrantLock:表示重入锁,它是唯一一个实现了Lock接口的类。重入锁指的是 线程在获得锁之后,再次获取该锁不需要阻塞,而是直接关联一次计数器增加重入次;syschronized和reenttrantlock都支持重入锁;重入锁的设计目的比如调用demo方法获得了当前的对象锁,然后在这个方法中再去调用 demo2,demo2中的存在同一个实例锁,这个时候当前线程会因为无法获得 demo2的对象锁而阻塞,就会产生死锁。重入锁的设计目的是避免线程的死 锁。Reentran.转载 2021-11-11 14:17:00 · 205 阅读 · 0 评论 -
重排序
数据依赖性如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。数据依赖分下列三种类型:名称代码示例说明写后读a = 1;b = a;写一个变量之后,再读这个位置。写后写a = 1;a = 2;写一个变量之后,再写这个变量。读后写a = b;b = 1;读一个变量之后转载 2017-01-27 12:02:51 · 391 阅读 · 0 评论 -
Callable、Future和FutureTask
创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。 如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。 而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。转载 2016-10-06 13:13:49 · 302 阅读 · 0 评论 -
多线程join学习
对于Java开发人员,多线程应该是必须熟练应用的知识点,特别是开发基于Java语言的产品。本文将深入浅出的表述Java多线程的知识点,在后续的系列里将侧重于Java5由Doug Lea教授提供的Concurrent并行包的设计思想以及具体实现与应用。 如何才能深入浅出呢,我的理解是带着问题,而不是泛泛的看。所以该系列基本以解决问题为主,当然我也非常希望读者能够提出更好的解决问题的转载 2016-10-16 21:20:15 · 283 阅读 · 0 评论 -
Java Thread.interrupt 害人中断JAVA线程
程序是很简易的。然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的、难以发现的错误。 在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程。 背景转载 2016-09-27 15:53:16 · 485 阅读 · 0 评论 -
偏向锁,轻量级锁,重量级锁
一:java多线程互斥,和java多线程引入偏向锁和轻量级锁的原因?--->synchronized的重量级别的锁,就是在线程运行到该代码块的时候,让程序的运行级别从用户态切换到内核态,把所有的线程挂起,让cpu通过操作系统指令,去调度多线程之间,谁执行代码块,谁进入阻塞状态。这样会频繁出现程序运行状态的切换,线程的挂起和唤醒,这样就会大量消耗资源,程序运行的效率低下。为了提高效率,jvm的开转载 2016-09-25 18:53:05 · 730 阅读 · 3 评论 -
同步屏障CyclicBarrier
简介CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告转载 2016-07-21 21:33:56 · 436 阅读 · 0 评论 -
CountDownLatch的使用
CountDownLatch是一个同步辅助类,犹如倒计时计数器,创建对象时通过构造方法设置初始值,调用CountDownLatch对象的await()方法则处于等待状态,调用countDown()方法就将计数器减1,当计数到达0时,则所有等待者或单个等待者开始执行。 1 package com.thread; 2 import java.util.concurrent.转载 2016-07-20 21:55:05 · 792 阅读 · 0 评论 -
Exchanger
Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据。当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行[java] view plain copypublic clas转载 2016-07-19 22:20:30 · 344 阅读 · 0 评论 -
非阻塞算法简介
Java™ 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能,java.util.concurrent 包充分地利用了这个功能。非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 —— 例如比较和交换。非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞吐率,对生存问题(例如死锁和优先级反转)也能提供更好的防御。在这期的 Ja转载 2016-07-06 21:51:10 · 1770 阅读 · 1 评论 -
非阻塞同步,CAS 原理分析
一、序言 前面我们提到的synchronized 等锁机制是一种阻塞同步,虽然它完成了我们的原子性操作,和线程安全,但是这种阻塞同步机制是比较耗费性能的,因为在阻塞和唤醒等状态转换中,是需要CPU指令进行帮忙实现,这要的调度是比较耗时的,因此这种策略是一种悲观策略,当然我们需要线程安全,又要高效,在一定情况下我们会采用非阻塞同步机制。转载 2016-07-06 16:37:40 · 1172 阅读 · 0 评论 -
自旋锁
锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及。本系列文章将分析JAVA下常见的锁名称以及特性,为大家答疑解惑。1、自旋锁自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界转载 2016-07-13 15:47:43 · 355 阅读 · 0 评论 -
流行的原子
在 JDK 5.0 之前,如果不使用本机代码,就不能用 Java 语言编写无等待、无锁定的算法。在 java.util.concurrent 中添加原子变量类之后,这种情况发生了变化.十五年前,多处理器系统是高度专用系统,要花费数十万美元(大多数具有两个到四个处理器)。现在,多处理器系统很便宜,而且数量很多,几乎每个主要微处理器都内置了多处理支持,其中许多系统支持数十个或数百个处理转载 2016-07-10 11:35:01 · 350 阅读 · 0 评论 -
volatile及指令重排序
一、不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它;我们在JDK及开源框架中随处可见这个关键字,但并发专家又往往建议我们远离它。比如Thread这个很基础的类,其中很重要的线程状态字段,就是用volatile来修饰,见代码 /* Java thread status for tool转载 2015-12-05 22:48:53 · 1476 阅读 · 0 评论 -
happens-before俗解
学习Java并发,到后面总会接触到happens-before偏序关系。初接触玩意儿简直就是不知所云,下面是经过一段时间折腾后个人对此的一点浅薄理解,希望对初接触的人有帮助。如有不正确之处,欢迎指正。synchronized、大部分锁,众所周知的一个功能就是使多个线程互斥/串行的(共享锁允许多个线程同时访问,如读锁)访问临界区,但他们的第二个功能 —— 保证变量的可见性 —— 常被遗忘。转载 2017-01-27 11:53:37 · 287 阅读 · 0 评论 -
Java并发——Synchronized关键字和锁升级,详细分析偏向锁和轻量级锁的升级
一、Synchronized使用场景Synchronized是一个同步关键字,在某些多线程场景下,如果不进行同步会导致数据不安全,而Synchronized关键字就是用于代码同步。什么情况下会数据不安全呢,要满足两个条件:一是数据共享(临界资源),二是多线程同时访问并改变该数据。例如:public class AccountingSync implements Runnable{ ...转载 2019-07-16 10:47:02 · 154 阅读 · 0 评论 -
ThreadLocal可能引起的内存泄露
threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好的做法是将调用threadlocal的remove方法. 在threadlocal的生命周期中,都存在这些引用. 看下图: 实线代表强引用,虚线代表弱引用. 每个thread中都存...转载 2018-11-26 22:29:02 · 158 阅读 · 0 评论 -
AQS源码分析
1.ReentrantLock和AQSReentrantLock中使用了AbstractQueuedSynchronizer也就是AQS,完成了锁的获取和释放等。从ReentrantLock类中进入,我们看到它的默认构造方法:public ReentrantLock() { sync = new NonfairSync();}默认使用的是非公平锁,而它的lock方法中,使...转载 2018-11-19 23:29:12 · 118 阅读 · 0 评论 -
jdk1.7的Java线程池架构原理和源码解析(ThreadPoolExecutor)
我们现在来看看ThreadPoolExecutor的源码是怎么样的,也许你刚开始看他的源码会很痛苦,因为你不知道作者为什么是这样设计的,所以本文就我看到的思想会给你做一个介绍,此时也许你通过知道了一些作者的思想,你也许就知道应该该如何去操作了。这里来看下构造方法中对那些属性做了赋值:源码段1:public ThreadPoolExecutor(int corePoolSize,转载 2018-04-04 13:59:31 · 570 阅读 · 0 评论 -
Java并发之彻底搞懂偏向锁升级为轻量级锁
网上有许多讲偏向锁,轻量级锁的文章,但对偏向锁如何升级讲的不够明白,有些文章还相互矛盾,经过对jvm源码(biasedLocking.cpp)的仔细分析和追踪,基本升级过程有了一个清晰的过程,现将升级流程阐述如下: 因为偏向锁,锁住对象时,会写入对象头相应的标识,我们先把对象头(官方叫法为:Mark Word)的图示如下(借用了网友的图片):通过转载 2018-04-03 09:15:00 · 333 阅读 · 0 评论 -
Spring ThreadPoolTaskExecutor队列满的异常处理
corePoolSize:默认开启线程数;maxPoolSize:最大线程数;queueCapacity:缓冲任务队列的长度;创建线程的方式:@Autowiredprivate ThreadPoolTaskExecutor threadPool;threadPoolTaskExecutor.execute(new Runnable() { p转载 2017-08-24 12:10:00 · 1645 阅读 · 0 评论 -
JOIN的线程谁来唤醒
1.join做了什么? 打开jdk的源码,可以看到join其实就是在等待目标线程的结束: public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (mil转载 2017-04-06 13:38:24 · 1600 阅读 · 1 评论 -
记一次synchronized锁字符串引发的坑兼再谈Java字符串
先看一段代码:public class StringThread implements Runnable { private static final String LOCK_PREFIX = "XXX---"; private String ip; public StringThread(String ip) { this.ip = ip;转载 2017-04-28 15:42:43 · 361 阅读 · 0 评论 -
Condition-线程通信更高效的方式
引入本篇的主角,Condition,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。下面将之前写转载 2017-03-26 12:33:08 · 312 阅读 · 0 评论 -
使用Java的DelayQueue容易碰到的一个坑
先看一下整个code吧:import java.util.concurrent.DelayQueue;import java.util.concurrent.Delayed;import java.util.concurrent.TimeUnit;public class DelayQueueExample {/** * @param args*/ public stat转载 2017-04-08 22:04:10 · 4919 阅读 · 0 评论 -
双重检查锁定原理详解
双重检查锁定与延迟初始化在Java程序中,有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化。此时程序员可能会采用延迟初始化。但要正确实现线程安全的延迟初始化需要一些技巧,否则很容易出现问题。比如,下面是非线程安全的延迟初始化对象的示例代码:public class UnsafeLazyInitialization {private stati转载 2017-03-20 22:15:55 · 684 阅读 · 0 评论 -
带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runnable是一种有很大局限的抽象,run方法中只能记录日志,打印,或者把数据汇总入某个容器(一方面内存消耗大,另一方面需要控制同步,效率很大的限制),总之不能返回执行的结果;比如同时1000个任务去网络上抓取数据,然后将抓取到的数据进行处理(处理方式不定),我觉得最好的方式就是提供回调接口,把处理的方式最为回调传进去;但是现在我转载 2016-05-22 23:03:57 · 572 阅读 · 0 评论 -
JDK并发工具包CompletionService和ExecutorCompletionService的好处和使用场景
《Java并发编程实践》一书6.3.5节CompletionService:Executor和BlockingQueue,有这样一段话:“如果向Executor提交了一组计算任务,并且希望在计算完成后获得结果,那么可以保留与每个任务关联的Future,然后反复使用get方法,同时将参数timeout指定为0,从而通过轮询来判断任务是否完成。这种方法虽然可行,但却有些繁琐。幸运的是,还有一种转载 2016-05-22 14:19:37 · 794 阅读 · 0 评论 -
使用CompletionService批处理任务
如果你向Executor提交了一个批处理任务,并且希望在它们完成后获得结果。为此你可以保存与每个任务相关联的Future,然后不断地调用timeout为零的get,来检验Future是否完成。这样做固然可以,但却相当乏味。幸运的是,还有一个更好的方法:完成服务(Completion service)。CompletionService整合了Executor和BlockingQueue的功能转载 2016-05-22 13:59:39 · 378 阅读 · 0 评论 -
慎重使用volatile关键字
Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。public volatile boolean exit = false;在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步转载 2014-07-31 00:21:42 · 1744 阅读 · 0 评论 -
sleep和wait的区别
1. Java中sleep和wait的区别① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep,sleep和wait都会让出cpu执行权,唯一的区别在于sleep不释放锁,到一定时间自动会醒,转载 2015-01-20 18:54:04 · 537 阅读 · 0 评论 -
Callable和Future创建线程
java5开始,提供了Callable接口,该接口是Runnable的增强版本,提供了一个call()方法作为执行体,但是call()方法比run()方法功能更强大。call():有返回值,可以声明抛出异常. java5提供FutureTask接口来代表Callable接口里面的call方法返回值,并提供了一个FutureTask的实现类,该实现类实现了Runnable接口,可以作为T原创 2015-01-18 16:40:38 · 673 阅读 · 0 评论 -
Java HashMap的死循环
在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历过,本来觉得没什么好写的,因为Java的HashMap是非线程安全的,所以在并发下必然出现问题。但是,我发现近几年,很多人都经历过这个事(在网上查“HashMap Infinite Loo转载 2015-01-18 19:26:46 · 502 阅读 · 0 评论 -
阻塞队列BlockingQueue
BlockingQueue作为线程同步的工具,并不是作为一个容器使用,它具有一个特征:当生产者线程试图向其放入元素的时候,如果队列已满,则该线程被阻塞,当消费者线程试图从BlockingQueue中取出元素时,如果队列已空,则该线程阻塞。BlockingQueue在jdk文档里面有如下几个方法: 抛出异常特殊值阻塞超时插入add(e)原创 2015-01-18 13:48:25 · 502 阅读 · 0 评论 -
Semaphore实现信号灯
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个原创 2015-01-17 19:37:19 · 544 阅读 · 0 评论 -
java 中 ReentrantReadWriteLock的读锁和写锁的使用
jdk文档中关于ReentrantReadWriteLock类使用的一个很好的例子,以下是具体的介绍: 在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。通常,在预期 collection很大,读取者线程访问它的次数多于写入者线程,并且 entail 操作的开销高于同步开销时,这很值得一试。例如,以下 是一个使用 Tre转载 2015-01-17 14:54:46 · 2712 阅读 · 0 评论 -
java生产者消费者
对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的。就像学习每一门编程语言一样,Hello World!都是最经典的例子。 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。对于此模型,应该明确一下几点:1、生产者仅仅在仓储未满时候生产,仓满则停止生产。2、消费者仅仅在仓储有产品时候才能消费,转载 2015-01-13 16:56:10 · 439 阅读 · 0 评论 -
一道多线程互相通讯的面试题目
要求启动三个线程,一个线程专门打印A,一个线程专门打印A,一个线程专门打印C,原创 2014-07-21 13:49:41 · 735 阅读 · 0 评论 -
培训机构多线程同步的面试题目
子线程循环10次,接着主线程循环100次,原创 2014-07-21 23:19:05 · 997 阅读 · 0 评论 -
ThreadLocal的理解
ThreadLocal是线程的局部变量,每个线程都有该变量,每个线程可以取用这个原创 2014-07-26 23:03:02 · 481 阅读 · 0 评论