Skip to the content.

[TOC]

线程

线程状态

线程有6种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIME_WAITING、TERMINATED

线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示(图源《Java 并发编程艺术》4.1.4 节):

Java+线程状态变迁

备注:原图中 wait 到 runnable 状态的转换中,join实际上是Thread类的方法,但这里写成了Object

补充知识:

线程池有5种状态:RUNNING,SHUTDOWN,STOP,TIDYING,TERMINATED。

在线程池中,用了一个原子类来记录线程池的信息,用了int的高3位表示状态,后面的29位表示线程池中线程的个数。

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

终止线程

方法

Stop

使用退出标志,说线程正常退出,但是stop函数停止线程过于暴力,它会立即停止线程,不给任何资源释放的余地。

中断

什么是中断?

Java提供的一种用于停止线程的机制——中断。

中断的相关方法
如何使用中断?

要使用中断,首先需要在可能会发生中断的线程中不断监听中断状态,一旦发生中断,就执行相应的中断处理代码。 当需要中断线程时,调用该线程对象的interrupt函数即可。

  1. 设置中断监听
Thread t1 = new Thread( new Runnable(){
    public void run(){
        // 若未发生中断,就正常执行任务
        while(!Thread.currentThread.isInterrupted()){
            // 正常任务代码……
        }

        // 中断的处理代码……
        doSomething();
    }
} ).start();

正常的任务代码被封装在while循环中,每次执行完一遍任务代码就检查一下中断状态;一旦发生中断,则跳过while循环,直接执行后面的中断处理代码。

  1. 触发中断
t1.interrupt();

上述代码执行后会将t1对象的中断状态设为true,此时t1线程的正常任务代码执行完成后,进入下一次while循环前Thread.currentThread.isInterrupted()的结果为true,此时退出循环,执行循环后面的中断处理代码。

如何处理中断?

上文都在介绍如何获取中断状态,那么当我们捕获到中断状态后,究竟如何处理呢?

线程池

Java中的线程池是如何实现的?

执行 execute()方法和 submit()方法的区别是什么呢?

如果提交任务的时候使用了submit,则返回的feature里会存有异常信息,但是如果数execute则会打印出异常栈。但是不会给其他线程造成影响。之后线程池会删除该线程,会新增加一个worker。

拒绝策略

Executors

newSingleThreadExecutor(单线程的线程池)

newFixedThreadPool (固定数目线程的线程池)

newCachedThreadPool(可缓存线程的线程池)

newScheduledThreadPool(定时及周期执行的线程池)

Executors 返回线程池对象的弊端如下:

线程池原理