多线程基本原理

DougLea 并发设计大师

为什么需要线程

单核到多核,达到并行计算,线程是轻量级,成本低,效率高
合理利用多核cpu资源,提升对计算机资源的利用

java中如何使用线程

  1. 继承Thread类,重写run方法
  2. 实现Runnable接口
  3. Callable带返回值的线程,返回值用Future接收
  4. ThreadPool线程池

实际应用

线程合理利用cpu资源,提高程序的吞吐量
比较多的实际是线程池,一般不会new一个线程来使用,线程有风险
使用new Thread造成资源不可控

如何去应用线程池?
对账,通过线程进行跑批
BIO模型优化

如何改造程序实现异步化处理?

并发基础

生命周期
线程共有六种状态
在这里插入图片描述
线程使用目的,提高程序的性能

java中的线程状态 6种
线程启动,终止
interrupt

锁(保护线程安全)
synchonic 修饰方法,修饰代码块,修饰实例
以上方法锁的范围不同。作用范围不同,锁的范围由对象生命周期决定的
锁的范围,为什么锁的范围会有影响,
互斥锁的本质:共享资源

锁,对象锁
java
这是jvm源码,这里保存对象头
在这里插入图片描述
下面这个就是对象头
在这里插入图片描述
轻量级锁,重量级锁,偏向锁,
加锁会带来性能开销,
在这里插入图片描述
偏向锁,轻量级锁,重量级锁

锁的升级

在这里插入图片描述
jdk1.6之前是加重量级锁,会导致性能下降,之后又优化,这里涉及锁的升级。这个是由jvm层面实现的,我们不用管。
针对不同情况进行优化,提高效率。

首先偏向锁,没有获取就会升级到轻量级锁,然后重量级锁,阻塞线程
所以优化就是,在线程阻塞前,抢占锁,轻量级或者偏向锁
让线程不阻塞,也可以抢占到锁。在不加锁情况解决线程安全问题

偏向锁(默认关闭,线程没有竞争时候提升性能,真是情况没有必要开启偏向锁,所以一般就是无锁,轻量级锁,重量级锁)
首先访问同步代码块,看对象头中是有存储了线程id,(上面对象头表中有)如果没有存储,会通过cas操作(CAS,乐观锁,保证原子性,比较并替换,比较预期数据和原始内存中数据是否一致)将其替换掉。当前线程会存储标记,这是在没有竞争的情况下,用偏向锁 如上图 1表示偏向锁,01表示锁的标记,ThreadId会有值。下图总共32位
在这里插入图片描述

如果现在有另一个线程访问,cas操作会失败,会撤销原来获得的偏向锁,暂停原来的线程,解锁,将对象头中的线程id设置为空,恢复到无锁状态,恢复线程。
如果原来线程正在运行,无法撤销,会升级锁为轻量级锁,然后以轻量级锁竞争锁对象

在这里插入图片描述
线程栈有Lock record,对象头Object复制到其中,owner指向锁对象
轻量级锁,栈中存储对象头,通过cas操作,指向占中的指针。当线程2进入,失败,重试机制,自旋锁,多次cas操作(线程获得锁和释放锁时间短),但是也不能一直重试,自适应自旋,会根据上一次抢占时间长短觉定这一次时间多少(底层实现),相比于线程阻塞,挂起的性能好,所以用自旋。如果在指定自旋(自适应自旋)此时还没有获得锁,自旋失败,修改为重量级锁,没有获得锁的线程阻塞,等待唤醒

重量级锁,队列中排队被阻塞的线程。
唤醒,进行新一轮的抢占

非公平锁,允许插队,syncholized

如何优化,存在竞争就会升级到重量级锁

生产者和消费者。两个不同的线程
在这里插入图片描述
线程通信(wait/notify)等待唤醒
wait作用,释放当前同步锁,实现线程阻塞
notify 唤醒被阻塞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值