线程的状态
1. new:线程创建后, 执行start方法前,处于new状态
2. runnable:执行start方法后,线程正在jvm中执行或者准备执行,在等待系统分配cpu资源
3. blocked:线程等待获取监视器锁,比如线程在尝试进入synchronized块或方法时锁被其他线程持有
4. waiting:线程无期限等待状态,通常由于手动执行了wait或park方法
5. timed_wating:wait或park方法带时间参数
6. terninated:线程终止状态,执行完run方法后进入终止状态
创建线程有哪些方式
在java中,对线程的封装主要是通过Thread类来实现的,它提供了两个关键的方法,start和run,调用start方法会触发底层的native方法start0,向操作系统申请线程的资源,并等待cpu调度,当线程被cpu调度后,会回调thread的run方法,在这个方法里执行我们定义的任务逻辑。因此启动线程的方式,只有thread的start方法,我们可以通过以下几种方式来指定我们的任务:
1. 继承Thread类,重写run方法
2. 实现runnable接口的run方法,通过Thread的构造器传入进去
3. 通过线程池,传入一个runnable的实现类
4. 结合futuretask或者callable接口实现异步任务的执行和获取返回结果
线程池如何实现线程复用
线程池实现线程复用的关键在于其内部维护的阻塞队列。
当线程执行完一个任务以后,它并不会立即结束,而是通过自旋的方式从阻塞队列里面去获取新的任务。
如果队列里有任务就继续执行新的任务,如果队列为空,那么会根据线程池的配置,比如核心线程数、超时时间、是否允许回收核心线程等来决定是否结束。比如线程数大于核心线程数或者允许核心线程回收,且线程在指定时间内没有获取到新的任务,线程就会被回收掉。如果线程数小于等于核心线程数且不允许回收核心线程,那线程会一直阻塞等待新的任务。