目录
1.线程的几种状态
2.TERMINATED状态
3.获取线程的状态
4.线程存在的意义
1.线程的几种状态
(1) NEW : 线程对象已经存在,但是线程没有启动
(2) RUNNABLE : 线程正在CPU上运行,或者可以在CPU上运行(就绪状态)
(3) TIME_WAITING : 线程当前处于堵塞状态.(wait/join)
(4) WAITING : 线程当前处于堵塞状态.(sleep)
(5) BLOCKED : 线程当前处于堵塞状态.(加锁操作)
(6) TERMINATED : 线程被释放,但是线程对象还在
线程图大致如下:
2.TERMINATED状态
为什么TERMINATED状态时,线程都已经回收了,对象不进行回收呢?
在Java中,一个线程对象只可以start一次,通常来讲,一个线程已经不存在了,那么线程对象也就没有作用了,之所以不同步将对象销毁,是因为Java对象的声明周期自有它的规则,这个生命周期和系统内核里面的线程并非完全一致,所以,内核的线程释放的时候,无法保证Java代码中的t对象也立即释放.
此时就需要一个特定的状态将t对象设置成"无效"(里面的属性方法还可以使用),因此一个线程只能start一次.
3.获取线程的状态
获取线程状态的方法是getStart(),是属性方法
可以观察以下代码的线程状态:
public class StartDemo1 {public static long count = 0;public static void main(String[] args) {Thread t = new Thread(() -> {for(int i = 0;i <100;i++) {try {Thread.sleep(15);} catch (InterruptedException e) {e.printStackTrace();}}});System.out.println("执行前状态: " + t.getState());t.start();for(int i = 0;i < 100;i++) {System.out.println("执行中状态: " + t.getState());}try {t.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("执行结束: " + t.getState());}
}
我们在main线程中创建了一个新的线程,这个新的线程的执行内容很简单,进入一个循环,执行100次的sleep(15),这个线程除了需要对循环条件的判断和对循环变量的自增之外,就只需要sleep.
同时在main线程中,执行完t.start之后,我们对t线程的状态进行100次的打印.
对计算机来说,15毫秒的时间是非常长的,因此,我们的打印结果绝大多数都是TIME_WAITING的状态,执行结果如下(结果太长,只截取一部分):
由上面这个代码可以观察到线程状态的交替.
4.线程存在的意义
通过下面的代码可以观察到多线程与单线程的区别
public class StartDemo2 {public static void main(String[] args) {serial();state();}public static long a = 0;public static long b = 0;public static void state() {long beg = System.currentTimeMillis();Thread t1 = new Thread(() -> {for(long i = 0;i < 100_0000_0000L;i++) {a++;}});Thread t2 = new Thread(() -> {for(long i = 0;i < 100_0000_0000L;i++) {b++;}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {throw new RuntimeException(e);}long end = System.currentTimeMillis();System.out.println("多线程消耗的时间: " + (end - beg) + "ms");}public static void serial() {long beg = System.currentTimeMillis();long a = 0;for(long i = 0;i < 100_0000_0000L;i++) {a++;}long b = 0;for(long i = 0;i < 100_0000_0000L;i++) {b++;}long end = System.currentTimeMillis();System.out.println("单线程消耗的时间: " + (end - beg) + "ms");}
}
通过运行的结果可以看出,多线程时间消耗要比单线程的时间消耗少很多,但是为什么两个线程却不是减半的效果呢?
因为线程如何调度是操作系统内核决定的,如果使用并行(两个内核执行两个线程),那么效果就是事半功倍,如果使用并发(一个内核执行两个线程),那么和单线程也没有区别了,当然即使全部都是并行,也不会出现减半的效果,因为线程在调度时也会有时间的损耗,并且,如果电脑上运行的程序过多,导致CPU的核心被占满了,那么再多的线程也没有用,因为根本无法支持并行的状态运行.