Java面试进阶:线程的生命周期

线程是系统调度的最小单元,一个进程可以包含多个线程,作为任务的真正运作者,有自己的栈(Stack)、寄存器(Register)、本地存储(Thread Local)等,但是会和进程内其他线程共享文件描述符、虚拟地址空间等。

影响线程状态的方法:

除了 start,还有多个 join 方法,等待线程结束;yield 是告诉调度器,主动让出 CPU;

基类 Object 提供了一些基础的 wait/notify/notifyAll 方法。如果我们持有某个对象的 Monitor 锁(这是前提),再调用 wait 会让当前线程处于等待状态,直到其他线程 notify 或者 notifyAll。所以,本质上是提供了 Monitor 的获取和释放的能力,是基本的线程间通信方式。

并发类库中的工具,比如 CountDownLatch.await() 会让当前线程进入等待状态,直到 latch 被基数为 0,这可以看作是线程间通信的 Signal。

 

守护线程(Daemon Thread)

daemonThread.setDaemon(true);必须在线程启动之前设置

 

ThreadLocal:

这是 Java 提供的一种保存线程私有信息的机制,因为其在整个线程生命周期内有效,所以可以方便地在一个线程关联的不同业务模块之间传递信息,比如事务 ID、Cookie 等上下文相关信息。

数据存储于线程相关的 ThreadLocalMap,其内部条目是弱引用,通常弱引用都会和引用队列配合清理机制使用,但是 ThreadLocal 是个例外,它并没有这么做。废弃项目的回收依赖于显式地触发,否则就要等待线程结束。这就是很多 OOM 的来源,所以通常都会建议,应用一定要自己负责 remove,并且不要和线程池配合,因为 worker 线程往往是不会退出的。

 

Java 的线程是不允许启动两次的,第二次调用必然会抛出 IllegalThreadStateException,这是一种运行时异常

写一个最简单的打印 HelloWorld 的程序,说说看,运行这个应用,Java 至少会创建几个线程呢?

使用以上两种方式获取的线程总数都是5个。
main
Attach Listener 在jdk6环境中是负责接收外部命令的,如jmap、jstack
Signal Dispatcher 外部jvm命令的转发器
Finalizer 处理用户的Finalizer方法
Reference Handler 处理引用对象本身的垃圾回收

idea debug启动,打断点,Frams下拉可以看到,完整的5个线程

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值