JAVA基础 多线程复习

🐴🐴🐴进程和线程的区别
由来

进程是资源分配最小单位 线程是CPU调度最小单位
区别

JAVA进程和线程的关系

JAVA程序默认一个main主线程 但JVM会创建多个线程 GC线程
🐴🐴🐴run和start方法的区别

🐴🐴🐴thread和runnable的关系


🐴🐴java向多线程中传递参数的三种方法详细介绍
https://www.jb51.net/article/31981.htm
构造函数
成员变量
回调函数
🐴🐴🐴🐴如何实现处理线程的返回值

🐴主线程等待法 不精准

🐴调用线程join()方法阻塞等待 线程处理结束 (粒度不够细)
https://blog.csdn.net/q5706503/article/details/84592449
🐴FutureTask/线程池(Future) 获取返回值

线程池可以提交多个callable任务 对任务进行管理

🐴🐴线程的状态 Thread类里的enum状态 结束之后再调用会抛 非法状态异常

🐴🐴🐴sleep和wait方法的区别



实例

🐴🐴🐴notify和notifyAll方法的区别

🐴🐴锁池 等待池
锁池为 线程A 给变量上锁阻塞后 阻塞的其他线程进入锁池 ENTRY LIST
等待池为 线程A wait之后进入等待池 被notify之后 重新进入锁池 竞争对象锁 WAIT SET
🐴🐴🐴yield
暗示线程调度器 让出当前cpu资源 (对锁无影响)
🐴🐴🐴interupt


如果被interupt了 检查flag

线程状态的改变

线程间的状态转换:

  1. 新建(new):新创建了一个线程对象。

  2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

  3. 运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。

  4. 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。

(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

  1. 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
    🐴🐴🐴线程安全的原因

    🐴🐴🐴synchronized互斥对象锁特点

    🐴🐴对象锁(方法锁)和类锁
    对象锁 锁对象

    类锁 锁类 类的所有对象 类锁对象锁 互不干扰

    🐴🐴总结

    🐴🐴🐴🐴synchronized底层原理
    JAVA对象头
    monitor

    🐴🐴对象头

    基本结构 存储堆中

    🐴🐴monitor锁 对象与生俱来 在java对象头中
    与 重量级锁 域相关联
    monitor锁源码 ObjectMonitor

    🐴🐴字节码 对象锁 与 方法锁 实例

    隐式 ACC_SYNCHRONIZEDflag

    多出的moniterExist为处理异常 释放monitor的指令
    🐴🐴锁的重入
    当对象拥有该对象锁时 内部再嵌套 该对象锁 依然可以
    🐴🐴synchronized缺点 (前期)
    前期 重量级锁 效率低

    🐴🐴🐴🐴synchronized优化

    🐴🐴自旋锁

    🐴🐴自适应自旋锁 JVM根据之前自旋时间 决定自旋时间

    🐴🐴锁消除


    🐴🐴锁粗化 一连串操作 对一个对象加锁 jvm会将加锁范围粗化到 一系列操作的外部 上一次锁


    🐴🐴synchronized四种状态 锁膨胀 和锁降级

    🐴🐴偏向锁 当线程获得锁时 记录线程id 之后不需要CAS操作加锁

    缺点:不适合 锁竞争激烈的 情况
    🐴🐴轻量级锁 自旋

    jvm实例


    解锁过程

    锁的内存语意 释放锁就是写到主内存中 获取锁是读主内存的修改
    markword在主存 堆中 display mark word为 本地复制

    🐴🐴特点总结

    🐴🐴吞吐量 暂停时间
    吞吐量为宏观 整体侧重
    暂停时间为 单次暂停侧重

    🐴🐴JSTACK分析线程 堆
    https://www.cnblogs.com/kongzhongqijing/articles/3630264.html
    🐴🐴🐴🐴synchronized和reentrant锁(再入锁)的区别
    继承AQS abstract queue synchronizer

    🐴🐴公平锁 避免饥饿情况(等待太久) 实现公平有额外开销

    🐴🐴reentrant lock有点 syn做不到的地方

    🐴🐴wait notify notifyAll对象化
    ArrayBlockingQueue 内部实现 互斥锁 Condition
    https://blog.csdn.net/qq_33788242/article/details/89765928
    signal /await
    🐴🐴condition
    https://www.jianshu.com/p/1c52f17efaab
    🐴🐴syn和reentrant区别

但是ReentrantLock提供了tryLock()、tryLock(long timeout, TimeUnit unit)、lock.lockInterruptibly()

tryLock() 方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false,而且线程可以立即离开去做其他的事情。

tryLock(long timeout, TimeUnit unit) 是一个具有超时参数的尝试申请锁的方法,阻塞时间不会超过给定的值;如果成功则返回true

lockInterruptibly() 获得锁,但是会不确定地发生阻塞。如果线程被中断,抛出一个InterruptedException异常。

🐴🐴JMM java内存模型

🐴🐴

🐴🐴工作内存

🐴🐴JMM与堆栈区别

🐴🐴主内存 /工作内存 区别 类似于 本地栈 与 堆的区别
在这里插入图片描述
🐴🐴🐴🐴JVM解决可见性问题
🐴🐴🐴happens before 原则 是判断是否线程安全的原则
在这里插入图片描述
🐴🐴🐴happens before 概念
如果happens before则 B可见A的修改
如果不 JVM可以重新排序
在这里插入图片描述
🐴🐴🐴volatile轻量级锁 并非绝对安全 保证写操作都被别的线程看到


🐴🐴🐴volatile实现原理
🐴🐴如何保证可见性

写时 会吧工作内存 刷新到主内存
读时 无效后只能从主内存中读取共享变量
🐴🐴如何禁止重排优化 内存屏障 保证了不重排 和 可见性


解决:给instance加上volatile 禁止重排
🐴🐴🐴🐴volatile和syn的区别

🐴🐴CAS 乐观锁

思想

一般不需要开发者去实现CAS

缺点

🐴🐴线程池 因为线程新增销毁 开销大 来重复利用
使用的原因


🐴🐴FORK JOIN

🐴🐴Executor的框架 都指向 excutor excutorService Scheduled

executor service为callable scheduled添加 定期

🐴🐴🐴🐴线程池处理任务逻辑(自定义线程池)

🐴🐴线程池构造函数

🐴🐴饱和处理策略

🐴🐴execute执行逻辑


🐴🐴ctl保存线程池状态 高3位为状态 后面为worker数

🐴🐴线程池的状态


🐴🐴线程池大小设定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值