轻量级锁:如果一个有多个线程访问,但多线程访问的时间是错开的,没有竞争,那么可以使用轻量级锁来优化;

monitor:重量级锁

正常我们使用synchronized时,没有竞争则是轻量级锁,当遇到竞争时,就会锁膨胀,变成重量级锁,一个对象拿到锁时,其他对象需要等待阻塞,使用monitor;

自旋优化:重量级锁竞争时,还可以使用自旋来进行优化,如果当前线程自选成功(即这时持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞。适用于多核cpu。自旋失败依旧会进行阻塞。

在ajva6之后自旋锁是自适应的,根据情况进行多自旋或少自选甚至不自旋;自选会占用cpu时间,单核cpu就是浪费,多核才能发挥优势;java7后不能控制是否开启自旋功能;

偏向锁:轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要CAS操作。java6中引入了偏向锁来做进一步优化;只有第一次使用CAS将线程ID设置到对象的Mark word头,之后每次看这个线程id是否是自己,发现是自己就没有竞争,就不用重新CAS。

可重入锁:就是一个对象中多个方法都加锁,且在调用某个加锁方法中接着调用其他加锁方法;

批量重偏向:现在有T1,T2两个线程,如果对象被多个线程访问,但是没有竞争,这时偏向了线程t1得对象仍有机会重新偏向T2,重偏向会重置对象的Tjread ID;  当撤销偏向锁阈值超过20次后(撤销后变成轻量级锁),jvm会觉得,是不是偏向错了,于是会给这些对象加锁时重新偏向至加锁线程;=

批量撤销:当撤销偏向锁阈值超过40次后,jvm会觉得自己确实偏向错了,根本就不该偏向,于是把整个类的所有对象都会变成不可偏向的,新建的对象也是不可偏向的。

锁消除:是对一些热代码,反复执行超过一点阈值后,使用JIT进行优化的加锁代码,对局部变量加锁的,永远不会有竞争时,就会把锁去消除掉,进而提升性能。

JIT即使编译器:当一些代码(热代码)反复执行,超过一点阈值,就会使用JIT即使编译器优化;当一个锁对某个局部变量加锁时,每次进来都是不用得局部变量加锁,JIT就会把synchronized给优化掉,相当于代码并没有使用synchronized;当两段代码执行,一个没有加锁,一个加锁了,两个都进行++操作,性能是差不多一致得,因为JIT进行了锁消除操作,进行了优化;也可以用一个命令来控制锁消除,默认是开启得,关闭锁消除后,加了锁得那段代码将不会被优化,性能会下降很多。

API 介绍
obj.wait() 让进入 object 监视器的线程到 waitSet 等待;wait可带参数,单位毫秒
obj.notify() 在 object 上正在 waitSet 等待的线程中挑一个唤醒
obj.notifyAll() 让 object 上正在 waitSet 等待的线程全部唤醒

sleep(long n) 和  wait(long n) 的区别

1) sleep 是 Thread 方法,而 wait 是 Object 的方法

2) sleep 不需要强制和 synchronized 配合使用,但 wait 需要和 synchronized 一起用

3) sleep 在睡眠的同时,不会释放对象锁的,但 wait 在等待的时候会释放对象锁

4) 它们状态 TIMED_WAITING

wait  notify正确用法

synchronized(lock) {
while(条件不成立) {
lock.wait();
}
// 干活
}
//另一个线程
synchronized(lock) {
lock.notifyAll();
}

模式之保护性暂停

Guarded Suspension,用在一个线程等待另一个线程的执行结果;

有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject;

如果有结果不断从一个线程到另一个线程,那么可以使用消息队列(生产者/消费组)

JDK中,join的实现,Future的实现,就是此模式;

说白了就是创建一个公共的对象,一个往里面设置值,一个从里面取值;

Java并发3的更多相关文章

  1. 多线程的通信和同步(Java并发编程的艺术--笔记)

    1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...

  2. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  3. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  4. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  5. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  6. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  7. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  9. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  10. JAVA并发编程J.U.C学习总结

    前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...

随机推荐

  1. 居中select中的option选项

    select经常有长短不一的选项:选择不同的选项居中不会生效: 使用text-align:center;text-align-last: center;  可以让所有选项都居中: 关于text-dec ...

  2. Mybatis模糊查询结果为空的解决方案

    写在前面 Mybatis使用模糊查询,查询结果为空的解决方案,我的代码是 select * from sp_user where 1=1 <if test="username!=nul ...

  3. Jedis的基本操作

    jedis jedis 是 redis推荐的java客户端.通过Jedis我们可以很方便地使用java代码的方式,对redis进行操作.jedis使用起来比较简单,它的操作方法与redis命令相类似. ...

  4. 机器学习---kmeans聚类的python实现

    """ Name: study_kmeans.py Author: KX-Lau Time: 2020/11/6 16:59 Desc: 实现kmeans聚类 " ...

  5. 使用基于Roslyn的编译时AOP框架来解决.NET项目的代码复用问题

    理想的代码优化方式 团队日常协作中,自然而然的会出现很多重复代码,根据这些代码的种类,之前可能会以以下方式处理 方式 描述 应用时可能产生的问题 硬编码 多数新手,或逐渐腐坏的项目会这么干,会直接复制 ...

  6. Mysql各版本号的含义

    1)MySQL Community Server 社区版本,开源免费,但不提供官方技术支持2)MySQL Enterprise Edition企业版本,需付费,可以试用30天3)MySQL Clust ...

  7. UML中类关系表示与Java代码中的对应关系

    UML中类关系表示与Java代码中的对应关系 1. 类的UML表示法 上图中,Employee 类有两个String类型的私有属性和一个返回值为String类型public 方法 getName(); ...

  8. 携程apollo配置中心服务端如何感知配置更新?

    引言 前面有写过一篇<分布式配置中心apollo是如何实时感知配置被修改>,也就是客户端client是如何知道配置被修改了,有不少读者私信我你既然说了client端是如何感知的,那服务端又 ...

  9. Golang 泛型的简单使用

    go 学习泛型,利用泛型编写对数据集合执行操作的方法.

  10. Java语言学习day37--8月12日

    今日内容介绍1.List接口2.Set接口3.判断集合唯一性原理 ###01List接口的特点 A:List接口的特点: a:它是一个元素存取有序的集合. 例如,存元素的顺序是11.22.33.那么 ...