Java基础—线程基础
线程,操作系统调度的最小单元。
线程状态
New:新创建状态。
实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。
Runnable:可运行状态
Java线程中将就绪(ready)和运行中(running)两种状态笼统的成为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得cpu 时间片后变为运行中状态(running)。
ready:就绪状态
- 就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。
- 调用线程的start()方法,此线程进入就绪状态。
- 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
- 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
- 锁池里的线程拿到对象锁后,进入就绪状态。
running:运行中状态
线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
Blocked:阻塞状态
表示线程阻塞于锁。
阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
Waiting:等待状态
进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
Timed waiting:超时等待状态
该状态不同于Waiting,它可以在指定的时间内自行返回。
Terminated:终止状态
表示该线程已经执行完毕或因为一个没有捕获的异常而中止了run方法,导致线程进入终止状态。
- 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
- 在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
说的差不多了~上图
理解中断
当一个线程调用interrupt()
方法时,线程的中断标识位将被置位(中断标识位为true),线程会不时的检测这个中断标识位,已判断是否应该被中断。
可以用Thread.currentThread().isInterruptd()
判断线程是否被置位。
可以用Thread.interruptd()
对中断标识进行复位(中断标识位=false)。
如果线程处于阻塞状态时,中断标识位被设置为true就会在阻塞方法调用处抛出InterruptException异常,并在抛出异常前将中断标识位复位为false。所以被中断的线程不一定会终止(底层代码里捕获InterruptException异常不做处理的情况)
介绍两种合理的处理方式
- 让外界通过
Thread.currentThread().isInterruptd()
判断是否终止线程。
void myTask() {
...
try{
sleep(50);
} catch(InterruptException e) {
Thread.currentThread().interrupt();
}
...
}
- 方法直接抛出异常,让调用者可以捕获
void myTask() throw InterruptException {
...
sleep(50);
}
安全地终止线程
- 中断来终止线程
public class MyThread {
public static void main(String[] args) throws InterruptedException {
MyRunner myRunner = new MyRunner();
Thread thread = new Thread(myRunner," myThread");
thread.start();
TimeUnit.MILLISECONDS.sleep(10);
thread.interrupt();
}
public static class MyRunner implements Runnable {
private long i;
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
i++;
System.out.println("i=" + i);
}
System.out.println("stop");
}
}
}
- volatile boolean变量控制线程
public class MyThread {
public static void main(String[] args) throws InterruptedException {
MyRunner myRunner = new MyRunner();
Thread thread = new Thread(myRunner," myThread");
thread.start();
TimeUnit.MILLISECONDS.sleep(10);
myRunner.cancel();
}
public static class MyRunner implements Runnable {
private long i;
private volatile boolean on = true;
@Override
public void run() {
while (on) {
i++;
System.out.println("i=" + i);
}
System.out.println("stop");
}
public void cancel() {
on = false;
}
}
}
运行结果
end
参考: