Java 并发编程三两事
文章平均质量分 89
并发编程一直是Java的重难点,希望在梳理知识点的同时,也能给大家分享一些我的收获。
CallMeJiaGu
个人博客:https://www.callmejiagu.com/
展开
-
多线程并发 之 synchronized 锁的优化
为了提高阅读的体验,可以点击这里前言早期版本的synchronized在性能上比较差,好在Jdk1.6之后对其进行种种优化,那么这篇我们就来学习一下synchronized锁都有哪些优化操作!因为网上关于这块的解析比较多了,所以基础如自旋、Mark Word就不再复述了,主要讲我对锁优化的认识!重量锁我觉得要想了解 synchronized 的优化,就必须要先认识到早期 synchron...原创 2019-01-06 14:05:28 · 700 阅读 · 1 评论 -
偏向锁、轻量锁、重量锁的理解
java中每个对象都可作为锁,锁有四种级别,按照量级从轻到重分为:无锁、偏向锁、轻量级锁、重量级锁。并且锁只能升级不能降级。在讲这三个锁之前,我先给大家讲清楚自旋和对象头的概念。自旋现在假设有这么一个场景:有两个线程A,B在竞争一个锁,假设A拿到了,这个时候B被挂起阻塞,一直等待A释放了锁B才得到使用权。在操作系统中阻塞和唤醒是一个耗时操作,如果A在很短的时间内就释放了锁,当这个时...原创 2018-03-04 12:59:04 · 8946 阅读 · 3 评论 -
java 并发编程之 ThreadLocal
ThreadLocal在Spring中发挥着重要的作用,在管理request作用域的Bean、事务管理、任务调度、AOP等模块都出现了它们的身影,起着举足轻重的作用。要想了解Spring事务管理的底层技术,ThreadLocal是必须攻克的山头堡垒。与synchronize不同的是,synchronize维护的是一个变量,而ThreadLocal是每一个线程都持有一份,就用空间换时间,而syn原创 2018-01-11 16:27:51 · 436 阅读 · 0 评论 -
线程池参数解析
线程池不恰当的设置会导致效率低下,设置低于单线程的效率。corePoolSize,核心线程数的个数。 当线程池被创建时,默认的情况下是没有线程产生的,除非调用了prestartCoreThread()的方法。这里假设没有调用prestartCoreThread(),那么一开始的时候线程的个数为0。直到有任务进来,每一个任务进来,就会对应一个线程的产生。当线程的个数达到核心线程的个数时,会把任务放到原创 2017-12-06 15:12:13 · 991 阅读 · 0 评论 -
Java并发编程 之 指令重排序
指令重排序 重排序的目的是提高运行并发度,发生在编译器和处理器阶段,遵循as-if-serial语义(不管怎么重排序,单线程程序的执行结果不能改变),也就是重排序所带来的问题是针对多线程的。 重排序发生的条件是A和B没有存在依赖关系,这里的依赖关系是指数据依赖关系和控制依赖关系两种。其中数据依赖表示两个以上操作访问同一个变量,且这两个操作中有一个为写操作。而控制依赖关系,比如if(a>0){in转载 2017-09-25 11:47:41 · 874 阅读 · 0 评论 -
Java并发编程 之 阻塞队列和CountDownLatch
前几天看到一个面试题目:有一个长度为2000的字符串,开三个线程去判断字符串中”u51”的个数。当时看到这个题目的时候,对并发编程是没有什么经验的,在实际项目多线程的应用也只有一两次。最近在恶补《Java并发编程的艺术》,对这个题目就有了解题的思路了。在这里记录一下对该题的解法和思路。一开始的时候,我能确定的是对“u51”个数相加是需要做同步处理,主要是如何去用三个线程去遍历这个字符串呢。需要保证索原创 2017-09-28 13:46:51 · 923 阅读 · 0 评论 -
Java并发编程 之 Condition与ReentrantLock的使用
先来看一道笔试题(迅雷的笔试题):编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。很明显考虑这题的时候,需要想到使线程之间能够的进行消息传递。这题如果想要用Object自带的wait和notify,相比于Condition感觉会更麻烦。wait和notify更容易实现两个线程之间的原创 2017-09-29 14:48:00 · 681 阅读 · 0 评论 -
Java并发编程 之 同步队列与等待队列
在上一篇博客中,我简单的介绍了对Condition和ReentrantLock的使用,但是想要更好的掌握多线程编程,单单会用是不够的。这篇我会针对Condition方法中的await和signal的实现原理来梳理一下我的理解。首先我们需要了解同步队列和等待队列的概念。简单的理解是同步队列存放着竞争同步资源的线程的引用(不是存放线程),而等待队列存放着待唤醒的线程的引用。同步队列中存放着一个个节点,当原创 2017-09-29 16:57:56 · 13519 阅读 · 11 评论 -
Java并发编程 之 volatile
国庆已经结束了,本该在国庆前就应该做好这篇笔记的,怎奈自己太懒,就在今天把前几天的知识梳理一下。在前几篇的博客介绍了一点并发编程的相关知识,今天我对volatile的原理简单的阐述一下。要想理解volatile的原理,需要对JMM(Java内存模式)有些了解。在实际的程序运行中,由于cpu执行速度很快,而从内存读取数据和向内存写入数据的过程跟cpu执行指令的速度比起来要慢的多,于是在cpu就引入了缓原创 2017-10-09 15:08:41 · 573 阅读 · 0 评论 -
Java并发编程 之 HashMap线程不安全
我想在平时的多线程编程中,容器的使用是很普遍的,但是你有没有考虑过有些容器是不安全的,如Haspmap、ArrayList。这里讲解一下Hashmap不安去体现在哪里。插入时不安全:如果有两个线程A和B,都进行插入数据,刚好经过哈希计算后得到的哈希码是一样的,即插入的位置是一样的。假设,线程A通过判断,该位置没有哈希冲突,还没有进行数据插入的时候,CPU就把资源让给了线程B。这时候线程B判断该位置也原创 2017-10-11 14:50:42 · 521 阅读 · 0 评论 -
Java并发编程 之 乐观锁和悲观锁
悲观锁可以把悲观锁想成一个很小心的人,无论做什么操作之前,都要去加个锁,这样别人想拿这个数据就会block直到它拿到锁。但是在效率方面,处理加锁的机制会产生额外的开销,还有增加产生死锁的机会。另外如果只有只读事物,这个锁是没必要的。 传统的关系型数据库里边就用到了很多这种锁机制,比如读锁,写锁等,都是在做操作之前先上锁。悲观锁的实现在java中,synchronized就是一种悲观锁的实现。这个很转载 2017-10-31 20:49:29 · 1647 阅读 · 0 评论