线程周期的不同状态,有着如下几种

新建 NEW,线程被创建时候还没启动,是个内部状态

就绪 RUNNABLE,已经在JVM中执行,需要执行计算资源,等待系统分配CPU片段,就需要等待排队

阻塞Blocked 就是等待lock

等待 等待资源的操作,一个常见的场景类似消费者模式,等待任务时候的挂起

计时等待,进入条件和等待状态类似,调用的存在超时条件方法

终止 线程已经退出了,线程完成了使命,也可以称为死亡

第二次调用的时候,线程可能处于其他非NEW的状态,无法进行再次启动

在Java中,什么是一个简单的线程,线程必然是系统调度的最小单元,线程可以包含多个部分 栈 寄存器 本地存储,并且还会和其他线程个屏幕共享文件描述符 虚拟地址空间等

具体实现上,操作系统还将其分为了内核线程,用户线程,不过在现在的Java中,所有线程都是映射到系统内核线程的对象

伴随着Java发展,也有着Go语言中协程的推进,Java也跟进了Fiber的机制

在线程声明周期中可以进行改变状态的因素有哪些呢?

除了自身的start,线程还有多个join,父进程等待子进程结束后运行,yield告诉调度器,释放自己持有的CPU,还有些已经被标记为过时的resume stop suspend之类的api,JDK最新版本中 destory和stop方法已经被移除

Object提供的一些基础wait/notify/notifyAll的方法,如果持有某个对象的Mointor,其他线程必须等待Monitor的释放

图片

Thread 和 Object中的并发并不好用

所以我们有了并发包的出现

然后是关于守护线程 Daemon Thread,应用需要一个长期的服务程序,

在所有线程都结束的时候也进行结束,这就是守护线程了

Thread daemonThread = new Thread();

daemonThread.setDaemon(true);

daemonThread.start();

还有就是慎用ThreadLocal,这是Java提供的一种保存线程私有信息的机制,方便在一个线程周期中使用上下文相关信息

但是内部是弱引用,但是回收要手动的依赖于部分api

static class ThreadLocalMap {

static class Entry extends WeakReference<ThreadLocal<?>> {

/** The value associated with this ThreadLocal. */

Object value;

Entry(ThreadLocal<?> k, Object v) {

super(k);

value = v;

}

}

// …

}

所以key为null的时候,条目就很容易就被回收了

一般来说弱引用要配合引用队列使用,但是ThreadLocal并没有这么做

所以其回收要显式的触发,要等待线程的结束,所以回收对应的ThraedLoclMap,这也是OOM的来源,通常建议,应用最好自己去remove

发表评论

邮箱地址不会被公开。 必填项已用*标注