Thread

这一节主要介绍线程的基本概念。

1. 什么是线程

  1. 一个程序同时执行多个任务。通常,每一个任务称为一个线程(thread),他是线程控制的简称。可以同时运行一个以上的线程的程序称为多线程程序。
  2. 进程和线程的区别在于,每个进程拥有自己的一整套变量,而线程则共享数据。在多数操作系统中,线程比进程更加“轻量级”,创建,撤销一个线程比启动新进程的开销要小的多。

2. 创建一个线程

下面是一个单独的线程执行一个任务的简单过程:

  1. 将任务代码移到实现了Runnable接口的类run方法中。这个接口非常简单,只有一个方法:

    public interface Runnable 
    {
    void run();    
    }

    由于runnable是一个函数式接口,可用lambda表达式建立一个实例:

    Runnable r = () -> {task code}
  2. 由runnable创建一个实例化对象:

    Thread t = new Thread(r);
  3. 启动线程

    t.start();

3. 中断线程

没有可以强制线程终结的办法。然而,interrupt方法可以用来请求终止线程。当对一个线程调用interrupt方法时,线程的终止状态将被置位。这是每一个线程都具有的终止标志,每个线程都该不时检查这个标志,以判断线程是否中断。

while(!Thread.currentThread().isInterrupted())
{
    do more work;
}

如果线程被阻塞(wait或sleep),就无法检测中断状态,这将产生InterruptedException异常。如果在每次迭代之后都调用sleep方法(或者其他的可中断方法),isInterrupted检测既没必要也没用处。如果在中断状态被置位时调用sleep方法他不会休眠。相反,它将清除这一状态,并抛出InterruptedException。

此外,有两个相似的方法,interrupted和isInterrupted。interrupted方法是静态的,它检测当前进程是否被中断,并且会清除该线程的中断状态。isInterrupted是一个实例方法,可用来检验是否有线程被中断。调用这个方法不会改变中断状态。

4. 线程状态

  1. 新创建线程: new的线程,未开始运行。
  2. 可运行线程: 一旦调用start()方法,线程处于runnable状态。一个可运行线程可能正在运行也可能没有运行。
  3. 被阻塞线程和等待线程: 暂时不活动,不运行代码,不消耗资源。
    1. 当一个线程获取一个内部对象锁,而该锁被其他线程拥有,则该线程进入阻塞状态。
    2. 当该线程等待另一个线程通知调度器一个条件时,自己进入等待状态。
    3. 调取超时参数时,进入计时等待状态
  4. 被终止的线程:因为run方法正常退出而自然死亡或者因为一个没有捕获的异常终止了run方法意外死亡。