Java 并发总结(三)
锁优化及注意事项
- 有助于提高锁的性能
- 减小所持有时间:例如不要对方法直接加锁,而是在方法中对具体访问临界资源的代码加锁
- 减小锁粒度:如ConcurrentHashMap
- 用读写锁代替独占锁
- 锁分离:如LinkedBlockingQueue,由于读写分别在队首和队尾,所以不对整个队加锁而是对队首和队尾分别加锁
- 锁粗化:当一个锁在某段时间对某一资源反复申请锁,可以现将锁分给此线程一段时间,阻塞其他线程
- Java虚拟机的锁优化
- 锁偏向:因为很有可能是同一个线程申请某个锁,所以如果一个线程获取了锁,那么就进入偏向模式,当此线程需要再次申请锁时,无需再进行同步操作。
- 轻量级锁:如果偏向锁实效,虚拟机不会立即挂起线程,而是会简单地将对象头部作为指针,指向持有锁的线程堆栈的内部,来判断一个线程是否持有对象锁,如果线程获得轻量级锁成功,则进入临界区,否则当前线程酒会膨胀为重量级锁
- 自旋锁:锁膨胀后,虚拟机为了避免线程在操作系统层面真正被挂起。系统会进行一次赌注,假设在不久的将来线程会获得锁,所有会让当前线程进行几个空循环,若经过几个时钟周期后获得锁,则进入临界区,否则真正挂起
- 锁消除:虚拟机在JIT编译时,对运行上下文进行扫描,去除不可能存在共享资源的竞争的锁。主要只是指JDK一些内置API,如StringBuffer、Vector。
- ThreadLocal:线程本地变量,为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
- synchronized是用时间保证安全,ThreadLocal是用空间保证安全
- 实现:
- ThreadLocal类有一个内部类ThreadLocalMap,用来保存键值对,当前ThreadLocal为键,要存储的副本为值。每一个Thread都有一个ThreadLocalMap类型成员threadLocals用来保存键值对
- 初始时,在Thread里面,threadLocals为空,当通过ThreadLocal变量调用get()方法或者set()方法,就会对Thread类中的threadLocals进行初始化,并且以当前ThreadLocal变量为键值,以ThreadLocal要保存的副本变量为value,存到threadLocals
- 详细说明:http://www.cnblogs.com/dolphin0520/p/3920407.html
- 无锁:无锁是一种乐观的策略,他会假设对临界区资源的访问是没有冲突的。无锁策略使用一种叫做比较交换的技术(CAS--Compare and swap),一旦检测到冲突,就重试当前操作直到没有冲突为止。
- 无锁没有竞争带来的系统开销,也没有频繁调度的开销
- 算法:三个参数,V要更新的变量、E预期值、N新值。仅当V值等于E值时,才会将V值设为N值,否则认为其他线程做了更新。最后CAS返回当前V真实值。当多个线程同时使用CAS操作一个变量时,只有一个会胜出,其余均失败,失败的线程不会被挂起,而是再次尝试,也允许放弃。总之,CAS操作需要给出一个期望值,也就是你认为现在变量应该是什么样子,如果不如你所愿,说明变量已经被修改过了,你需要重新去读变量值,再修改。
Java 并发总结(三)的更多相关文章
- Java并发编程三个性质:原子性、可见性、有序性
并发编程 并发程序要正确地执行,必须要保证其具备原子性.可见性以及有序性:只要有一个没有被保证,就有可能会导致程序运行不正确 线程不安全在编译.测试甚至上线使用时,并不一定能发现,因为受到当时的 ...
- 【JAVA并发第三篇】线程间通信
线程间的通信 JVM在运行时会将自己管理的内存区域,划分为不同的数据区,称为运行时数据区.每个线程都有自己私有的内存空间,如下图示: Java线程按照自己虚拟机栈中的方法代码一步一步的执行下去,在这一 ...
- 【Java并发核心三】CountDownLatch、CyclicBarrier及Phaser
个人感觉,看书学习还是需要“不求甚解”,因为一旦太过于计较小的得失,就容易钻牛角尖,学习进度也慢.我们完全可以先学一个大概,等到真正用到的时候再把那些细节丰富起来,就更有针对性. 所以,针对java并 ...
- 【Java并发编程三】闭锁
1.什么是闭锁? 闭锁(latch)是一种Synchronizer(Synchronizer:是一个对象,它根据本身的状态调节线程的控制流.常见类型的Synchronizer包括信号量.关卡和闭锁). ...
- Java并发(三)线程池原理
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 1. 降低资源消耗.通过重复利用已创建的线程降低线程 ...
- Java并发编程 (三) 项目准备
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.案例环境初始化 1.环境搭建与准备 Spring Boot 项目,https://start.spr ...
- Java并发(三):重排序
在执行程序时为了提高性能,提高并行度,编译器和处理器常常会对指令做重排序.重排序分三种类型: 编译器优化的重排序.编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. 指令级并行的重排序 ...
- 和朱晔一起复习Java并发(三):锁(含锁性能测试)
这个专题我发现怎么慢慢演化为性能测试了,遇到任何东西我就忍不住去测一把.本文我们会大概看一下各种锁数据结构的简单用法,顺便也会来比拼一下性能. 各种并发锁 首先,我们定一个抽象基类,用于各种锁测试的一 ...
- java并发系列(三)-----ReentrantLock(重入锁)功能详解和应用演示
1. ReentrantLock简介 jdk中独占锁的实现除了使用关键字synchronized外,还可以使用ReentrantLock.虽然在性能上ReentrantLock和synchronize ...
随机推荐
- Delphi中点击网页弹出的Alert对话框的确定按钮
思路: 使用Windows API函数遍历窗口,查找指定标题的窗口,然后从该窗口查找确定按钮,向该按钮发送鼠标消息进行模拟点击.由于IE8由Alert弹出的网页对话框的标题是“来自网页的消息”,而IE ...
- goroutine 需要注意的一个小细节
虽然goroutine 是并发执行的,但是它们并不是并行运行的.如果不告诉Go 额外的东西,同一时刻只会有一个goroutine 执行.利用runtime.GOMAXPROCS(n) 可以设置goro ...
- web跨域问题解决方案
在前端开发及调试过程中总能遇到浏览器报如下错误: Response to preflight request doesn't pass access control check: No 'Access ...
- unittest框架学习笔记三之testsuite
# coding=utf-8 '''created :2018/3/29 author:star project: testsuite'''import unittest,time,osfrom ba ...
- Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别 Pig
Hadoop生态上几个技术的关系与区别:hive.pig.hbase 关系与区别 Pig 一种操作hadoop的轻量级脚本语言,最初又雅虎公司推出,不过现在正在走下坡路了.当初雅虎自己慢慢退出pig的 ...
- mybatis执行test07测试类却显示test05测试类调用的sql语句出错
1.测试类 @Test public void test07() { IStudentDao studentDao = new IStudentDaoImpl(); Student student = ...
- UI自动化ADB出现devices offline的解决方法
终端运行如下命令即可解决: adb kill-server adb start-server adb remount
- JDK8新特性之Stream流
是什么是Stream流 java.util.stream.Stream Stream流和传统的IO流,它们都叫流,却是两个完全不一样的概念和东西. 流可以简单的说是处理数据集合的东西,可以申明式流式A ...
- 高级UI晋升之常用View(三)中篇
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从ViewPager来介绍常用View:文章目录 一.简介 二.基本使用 ...
- java中Date日期类型的大小比较
方法一:java.util.Date类实现了Comparable接口,可以直接调用Date的compareTo()方法来比较大小 String beginTime = "2018-07-28 ...