线程中断:
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变量。
当父线程创建子线程的时候,构造函数会把父线程的本地变量复制一份给子线程使用
原文:https://www.cnblogs.com/dwj-ngu/p/14607862.html