【JUC-3】共享模型管程相关:synchronized&lock,Monitor,wait&notify,park&unpark,ThreadLocal

本文参考:https://nyimac.gitee.io/2020/06/08/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/#1%E3%80%81%E5%85%B1%E4%BA%AB%E5%B8%A6%E6%9D%A5%E7%9A%84%E9%97%AE%E9%A2%98

  1. 知道synchronized使用方法
  2. 知道变量是否逃逸,分析安全性(例如方法内的局部变量是安全的,因为与栈帧同时销毁)
  3. 只有读操作共享也安全
  4. synchronized底层原理是Monitor,Monitor用来识别锁对象(synchronized括号内的对象)是否已经被持有,它包含一个Owner属性,记录当前锁对象绑定的线程
  5. Monitor首先与锁对象绑定这样其它进程来访问时会查看Monitor。
  6. 线程查看Monitor如果已有主人就去EntryList里面去等待(阻塞)
  7. 各种级别的锁的特点:轻量锁,锁膨胀,自旋锁,偏向锁(所谓轻量锁就是没用monitor 而是用了thread record 放入锁对象object的头记录当中 )
  8. 知道CAS概念:compare and swap 属于乐观锁
  9. 了解wait&sleep&notify等特点 等待队列waitset与entrylist
  10. 知道park的作用机制:notify只是随机的唤醒进程,使用unpark可以指定唤醒进程
  11. 在synchronized阻塞的线程(blocked)使用interrupt会打断阻塞进入runnable,而对于reentrantLock的interrupt是直接终止线程进入terminate
  12. 了解ThreadLocal与inheritableThreadLocal作用机制

synchronized使用

synchronized(对象) {
	//临界区(不可由其他进程的打断的功能代码)
}

synchronized加在成员方法上

public class Demo {
	//在方法上加上synchronized关键字
	public synchronized void test() {
	
	}
	//等价于
	public void test() {
		synchronized(this) {
		
		}
	}
}

分析线程安全

在这里插入图片描述
在这里插入图片描述

Monitor机制

在这里插入图片描述

CAS机制

在这里插入图片描述

分级别上锁

推荐参考https://nyimac.gitee.io/2020/06/08/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/#4%E3%80%81Monitor%E6%A6%82%E5%BF%B5

wait&notify&sleep

在这里插入图片描述

在这里插入图片描述

保护性暂停模式

park&unpark

使用park唤醒指定进程,park不会释放锁
在这里插入图片描述

状态转换

只有当线程创建并竞争时会进入blocked状态,其它调用方法会线程进入waiting或者是timed_waiting。

定位死锁

参考原文

ReentrantLock

还有可重入的特点
在这里插入图片描述

threadlocal

在每个线程内部都有一个名为threadLocals的成员变量,该变量的类型为HashMap,其中key为我们定义的ThreadLocal变量的this引用,value则为我们使用set方法设置的值。每个线程的本地变量存放在线程自己的内存变量threadLocals中

只有当前线程第一次调用ThreadLocal的set或者get方法时才会创建threadLocals(inheritableThreadLocals也是一样)。其实每个线程的本地变量不是存放在ThreadLocal实例里面,而是存放在调用线程的threadLocals变量里面

InheritableThreadLocal

它能够让父线程中ThreadLocal的值传给子线程。

也就是从main所在的线程,传给thread1或thread2

使用

public class Demo1 {
   public static void main(String[] args) {
      ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();
      InheritableThreadLocal<String> stringInheritable = new InheritableThreadLocal<>();

      // 主线程赋对上面两个变量进行赋值
      stringThreadLocal.set("this is threadLocal");
      stringInheritable.set("this is inheritableThreadLocal");

      // 创建线程
      Thread thread1 = new Thread(()->{
         // 获得ThreadLocal中存放的值
         System.out.println(stringThreadLocal.get());

         // 获得InheritableThreadLocal存放的值
         System.out.println(stringInheritable.get());
      });

      thread1.start();
   }
}

原理
InheritableThreadLocal类通过重写getMap和createMap,让本地变量保存到了具体线程的inheritableThreadLocals变量里面,那么线程在通过InheritableThreadLocal类实例的set或者get方法设置变量时,就会创建当前线程的inheritableThreadLocals变量。

当父线程创建子线程时,构造函数会把父线程中inheritableThreadLocals变量里面的本地变量复制一份保存到子线程的inheritableThreadLocals变量里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值