# ThreadLearning **Repository Path**: SteveLai524_admin/ThreadLearning ## Basic Information - **Project Name**: ThreadLearning - **Description**: Learning Thread Source - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-07-29 - **Last Updated**: 2022-06-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 如何解决线程安全的问题 ## 核心思想:上锁 分布式锁 在同一个jvm中,多个线程需要竞争锁的资源,最终只能够又一个线程能够获取到锁,多个线程同时 抢同一把锁,那个线程能够获取到锁,那个线程就可以执行相关代码,如果没有获取锁成功,中间需要经历锁的升级过程 如果一直没有获取到锁则会一直阻塞等待。 *如果线程A获取锁成功,但是线程A一直不释放,那么需要这个锁的线程就会一直陷入阻塞等待过程中* * synchronized是非公平锁就是看运气,所以如果那个先拿到的话就可以执行,如果实在函数中,那么就变成了执行一个函数 * synchronized如果加在一个实例方法上,则使用的是this锁。 * synchronized如果加在一个方法上。则使用的是当前的class锁 通过Jconsole中可以查看到死锁相关 ### 线程如何实现同步?----线程如何保证线程安全性 * 使用synchronized锁,从jdk1.6开始,锁的升级过程 偏量锁->轻量锁->重量锁 * 使用Lock锁(JUC),需要自己实现锁的升级过程。底层是基于aqs+cas实现。*不属于重量锁* * 使用ThreadLocal,需要注意内存泄露的问题 * 原子类CAS,非阻塞式 锁的相关方法 * wait 释放当前锁资源, 同时当时线程回阻塞 * yield * Join方法(底层是使用wait进行处理锁的,但是唤醒状态是通过jvm实现的) * notify 之后不一定能立马拿到锁,也是需要重新竞争锁的 *BlockedThreads entryList 会存放被阻塞的线程 waitList* 多线程的七种状态 * 新建状态(初始化状态) * 就绪状态 * 运行状态 * 死亡状态 * 阻塞状态 * 超时等待状态 * 等待状态 ![img.png](img.png) * 理解多线程 * synchronized * 多线程之间的通讯方式(notify,wait, join) * Sleep可以避免CPU 100% 运行 线程的停止,是通过自己编写intercepted属性中断请求处理 Synchronized属于JDK关键字,底层属于C++虚拟机底层实现 Lock锁底层给予AQS实现---如果比较菜就会变为重量级(ReentrantLock) Synchronized底层远离----锁的升级过程 Lock过程中 需要注意获锁,释放锁 ### Join Sleep Wait的区别 * Join方法要求先执行另一个线程之后在执行线程,实际上是wait * Sleep是让出CPU执行,睡眠时不释放锁 * Wait方法在等待的过程中释放锁