Java_线程
生命周期图
状态
五种状态:
- 新建状态(New)当新建线程的时候,就会进入新建状态。此时由 JVM 其分配内存,并初始化其成员变量的的值。
- 就绪状态(Runnable)当调用 start() 方法,线程就会处于 就绪状态,这是告诉 CPU “我已经准备好执行了,就差您的任务分配了”。
- 运行状态(Running) 运行状态就是说,线程的任务正在被执行了。
- 阻塞(Blocking) 阻塞分为<等待阻塞>,<同步阻塞>,<其他阻塞>。
- 死亡状态(Dead)线程已经执行完成或因抛出异常导致出错。
阻塞
阻塞分为以下几种:
- 同步阻塞
同步阻塞是指,因为争取同步锁(当锁被他人调用的时候)时失败了,使得线程进入同步状态。也就是,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。 - 等待阻塞
等待阻塞是指,调用 wait() 方法,使得线程进入等待状态。也就是 o.wait() -> 等待队列。 - 其他阻塞
通过调用线程的 sleep() 或 join() 或发出了 I/O 请求时,线程会进入到阻塞状态。当 sleep() 状态超时、 join() 等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。
终止线程的几种方式
- 正常运行结束
- 使用退出标志退出线程
- Interrupt 方法结束线程
有两种情况:
1. 线程处于阻塞状态。如果使用了 sleep,wait,还有 socket 的receive,accept 方法时,会使线程处于阻塞状态。当调用 interrupted 方法的时候,会抛出 InterruptException 异常,通过代码捕捉异常,使用 break 跳出循环,从而让我们有机会完成线程终止。
2. 线程处于非阻塞状态。使用线程方法 isInterrupted 方法判断是否已经中断了,然而执行对应的操作。
方法判断是否已经中断了,然而执行对应的操作。
public class ThreadSafe extends Thread {
public void run() {
while(!isInterrupted) {
try{
Thread.sleep(5*1000);
}catch(Exception e) {
e.printStackTrace();
break;
}
}
}
}
- stop 方法(不推荐,因为这就像电脑被突然被拔掉电源一样,资料还没有被保存就关机了,这样会对系统造成问题。)
sleep 和 wait 的区别
第一个区别在于,sleep 是属于 Thread 类的方法,而 wait 是属于 Object 的方法。
第二个是,sleep 是方法的参数是一个时间长度,指的是睡眠时间的长度。这时候线程不会被 CPU 调度,但是依旧是其监控的保持者,也就是不会释放对象的锁。而 wait 的话,线程会放弃对象锁,并出让 CPU 不参与调度,然后进入对象锁锁池,等待 notify 或 notifyAll 方法来唤醒。只有被唤醒才会重新进入就绪状态。
start 和 run 的区别
- start 方法来启动线程,真正实现了多线程的运行。这时无须等待 run 方法代码执行完毕,可以直接继续执行下面代码
- 通过 Thread 类的 start 方法启动一个线程,这时线程处于就绪状态,并没有运行
- run 方法称为线程体,它包含了要执行的这个线程的内容,线程进入了运行状态,开始运行 run 函数当中的代码。run 方法运行结束,此线程终止,然后 CPU 调度其他线程。