这一节主要介绍线程的基本概念。
1. 什么是线程
- 一个程序同时执行多个任务。通常,每一个任务称为一个线程(thread),他是线程控制的简称。可以同时运行一个以上的线程的程序称为多线程程序。
- 进程和线程的区别在于,每个进程拥有自己的一整套变量,而线程则共享数据。在多数操作系统中,线程比进程更加“轻量级”,创建,撤销一个线程比启动新进程的开销要小的多。
2. 创建一个线程
下面是一个单独的线程执行一个任务的简单过程:
将任务代码移到实现了Runnable接口的类run方法中。这个接口非常简单,只有一个方法:
public interface Runnable { void run(); }
由于runnable是一个函数式接口,可用lambda表达式建立一个实例:
Runnable r = () -> {task code}
由runnable创建一个实例化对象:
Thread t = new Thread(r);
启动线程
t.start();
3. 中断线程
没有可以强制线程终结的办法。然而,interrupt方法可以用来请求终止线程。当对一个线程调用interrupt方法时,线程的终止状态将被置位。这是每一个线程都具有的终止标志,每个线程都该不时检查这个标志,以判断线程是否中断。
while(!Thread.currentThread().isInterrupted())
{
do more work;
}
如果线程被阻塞(wait或sleep),就无法检测中断状态,这将产生InterruptedException异常。如果在每次迭代之后都调用sleep方法(或者其他的可中断方法),isInterrupted检测既没必要也没用处。如果在中断状态被置位时调用sleep方法他不会休眠。相反,它将清除这一状态,并抛出InterruptedException。
此外,有两个相似的方法,interrupted和isInterrupted。interrupted方法是静态的,它检测当前进程是否被中断,并且会清除该线程的中断状态。isInterrupted是一个实例方法,可用来检验是否有线程被中断。调用这个方法不会改变中断状态。
4. 线程状态
- 新创建线程: new的线程,未开始运行。
- 可运行线程: 一旦调用start()方法,线程处于runnable状态。一个可运行线程可能正在运行也可能没有运行。
- 被阻塞线程和等待线程: 暂时不活动,不运行代码,不消耗资源。
- 当一个线程获取一个内部对象锁,而该锁被其他线程拥有,则该线程进入阻塞状态。
- 当该线程等待另一个线程通知调度器一个条件时,自己进入等待状态。
- 调取超时参数时,进入计时等待状态
- 被终止的线程:因为run方法正常退出而自然死亡或者因为一个没有捕获的异常终止了run方法意外死亡。