Java-多线程并发03并发基础知识

线程中断:

java的中断并不是真正的通断,是一种线程协作机制,设置线程的中断标志,然后交给线程根据中断的状态自行处理

interrupt:中断线程,当调用线程的interrupt仅仅是设置了中断标志,如果线程使用了wait,join,sleep会被阻塞挂起

interrupted:判断是否被中断,方法内部获取的是当前调用线程(currentThread)的中断标志而不是调用的interrupt方法的实例对象。底层调用的还是isInterrupted,并清除中断标志。

 

 

isInterrupted(boolean):检测当前是否被中断,return true说明有中断标志。 参数说明是否清除中断标志。默认不清除标志。

 

 通过判断是否存在中断标志来退出线程

可以通过interrupt强制让阻塞挂起的睡眠抛出异常返回。

 

 

上下文切换:

CPU时间片使用完处于就绪状态时,线程被其他线程中断时。

 

死锁的条件:

互斥:争抢同一个资源

请求并持有: 持有资源的同时请求其他的。

不可剥夺:线程获取到的资源不可以被剥夺
环路等待:像个环一样,每一个都请求另一个

 

首先:资源是互斥使用的,然后持有等待另一个资源,由于资源不可剥夺无法释放,就造成了环路等待。  也就是构成了死锁。

破坏任何一个条件都会解决死锁问题。

 

守护线程和用户线程:

daemon(守护线程):比如辣鸡回收线程

user(用户线程):MAIN函数所在线程

用户线程完全结束,JVM才会正常退出,不会管守护线程是否结束。

用户线程还存在的情况下JVM不会终止。

设置守护线程:setDaemon(true)

 

main线程运行结束后,JVM会启动一个DestroyJavaVM的线程,该线程等待所有的用户线程结束后终止JVM。

如果希望主线程结束后JVM进程马上结束,那么可以在创建线程时将其设置为守护线程

如果希望主线程结束后子线程继续工作,可以设置为用户线程

 

ThreadLocal:

static ThreadLocal<String>  localVariable = new ThreadLocal<String>();

解决同时共享变量的线程安全问题。

创建一个变量后,每个线程对其访问的时候访问的是自己线程的变量。

每个访问这个变量的线程都会拥有这个变量的一个本地副本。

创建一个ThreadLocal变量后,每个线程都会复制一个变量到自己的本地内存中。

在每个线程中threadlocal变量的副本,其他线程是无法访问到的。

 

 每个线程的本地变量并不是存放在创建他们的ThreadLocal的实例中,而是存放在每个线程自己的threadLocal里面:

 

这个变量在Thread类中定义

 

当需要调用threadLocal变量时候,通过currentThread获取调用线程然后取出。为什么要用Map去存放?因为会有多个threadLocal值需要存放。

ThreadLocalMap的底层是一个定制化的HashMap

 

 ThreadLocal源码分析:

Set方法:

 

 

 

 根据getMap的取值是否为空来判断是否是第一次调用get方法,如果是第一次调用get就创建。否则的话就把传回来绑定。

 

T Get:

 

 

 

 如果不为空就返回对应的值进行绑定。

如果为空进行初始化

 

 

 

 如果threadLocal变量不为空就设置为null.

这里的initialValue是return  null

 

 为空就createMap初始化。应该是在创建的时期才会调用。

 

remove:

 

 获取当前线程的ThreadLocalMap,如果不为空,删除指定的ThreadLocal实例的本地变量,key就是this引用。

因为如果线程不消失,threadlocal变量就会一直存在,所以可能会出现内存溢出的问题。

要在使用完毕后手动去remove掉threadlocal变量

threadlocal没有继承性,在父线程设置的本地变量不会在子线程中继承。

 

inheritableThreadLocal:

继承自ThreadLocal,可以让子线程访问父线程设置的本地变量.

在inheritableThreadLocal中。 操作的变量不再是ThreadLocal,而是inherit able Thread Local变量。

 

 重写了三个方法。

 

 

 

 

 

 在创建线程时候,调用init,获取当前的线程,当前的线程就是父线程。判断父线程是否存在inherit变量,如果不为null,会执行createinheritMap。

createInheritMap中,使用父线程的inherit变量作为参数构造一个新的ThreadLocalMap赋值给子线程的inheritThreadLocals变量。

别问为什么用Map了,因为值可能不止一个。

在ThreadLocalMap中:

 

 在ThreadLocalMap构造器中,把父线程的inheritableThreadLocals成员变量的值复制到新的ThreadLocalMap对象中,

其中

 

 childvalue是inheritthreadlocal重写的方法。

 

原理是:InheritThreadLocal重写createMap和getMap方法,让本地变量保存到了定义的一个inheritableThreadLocal中,线程通过inherit类实例进行set和get方法设置变量时,就会创建当前线程的inherit变量。

当父线程创建子线程的时候,构造函数会把父线程的本地变量复制一份给子线程使用

 

posted @ 2021-04-01 19:55  NobodyHero  阅读(51)  评论(0编辑  收藏  举报