线程的状态转换
Daemon线程
一般工作线程是非daemon线程,后台线程是daemon线程。
如果jvm里的工作线程都停止了,比如main线程之类的都执行完了,那么daemon线程就会跟着jvm进程一起退出,不会像工作线程一样阻止jvm进程退出。daemon线程在退出的时候并不会执行finnaly块中的代码。
实际应用:微服务注册中心负责接收请求的核心工作线程突然停止了,那么说明这个微服务注册中心必须停止,结果监控微服务存活状态的线程一直在那儿运行着,会导致微服务注册中心没法退出的,因为jvm进程没法结束。
//负责监控微服务存活状态的后台线程
private Daemon daemon;
public ServiceAliveMonitor() {
this.daemon = new Daemon();
daemon.setDaemon(true);
}
private class Daemon extends Thread {
public void run() {}
}
终止线程
interrupt打断一个线程,其实是在修改那个线程里的一个interrupt的标志位,打断他以后,interrupt标志位就会变成true,所以在线程内部,可以根据这个标志位,isInterrupted这个标志位来判断,是否要继续运行。
实际应用:优雅关闭心跳线程。
//关闭心跳线程
public void shutdown() {
this.isRunning = false;
this.heartbeatWorker.interrupt();
}
//心跳线程
private class HeartbeatWorker extends Thread {
public void run() {
while(isRunning) {}
}
}
ThreadLocal
ThreadLocal:线程本地副本,避免多个线程并发的访问同一个共享的数据。一个Thread可以放多个ThreadLocal对应的本地变量副本。
实现原理:内部有一个ThreadLocalMap内部类,代表了一个map,每个Thread线程对象自己内部就有一个核心的数据结构是map。