JavaEE->多线程1
目录
一、进程
1.什么是进程
2.内存分配 - 内存管理
3.进程中通信
4.多进程
二、线程
1.什么是线程
2.线程的优势
3.进程与线程的区别(常见面试题)
三、Java中的线程
1.如何用Java创建一个线程
2.第一个多线程程序
3.用run()方法执行线程
4.面试题
5.使用jConsole.exe查看JVM中线程的状态
6.创建线程的另一种方式(Runnable)
7.例子
8.通过创建Thread匿名内部类的方式创建线程
9.通过创建Runnable接口的匿名内部类的方式来创建一个线程
10.通过Lambda表达式创建一个线程(推荐方式)
四、多线程的优势
1.单线程
2.分别两个线程
五、Thread类及常见的方法
1.Thread的常见构造方法
2.为线程起一个名字
3.获取线程名
4.Thread的几个常见属性
5.设置为后台进程
6.线程是否存活
7.线程中断
7.1通过共享的标记来进⾏沟通
7.2调⽤ interrupt() ⽅法来通知
1.sleep状态处理中断
2.正常执行状态下中断线程
8.等待一个线程
六.线程的状态
1.观察线程状态
2.观察线程中所有的状态
3.线程状态和状态转移的意义
一、进程
1.什么是进程
操作系统:
1.对下(硬件)管理更多计算机设备
2.对上(软件)为各种软件提供一个稳定运行环境
描述进程:进程控制块(PCB)
1.PID(标识系统中正在运行的进程)
2.内存指针:程序运行之前操作系统会为它分配一份有效的内存空间
3.文件描述符表(集合):程序运行起来需要访问一些文件资源,操作系统负责为程序分配资源
4.进程的状态:就绪,阻塞
5.进程的优先级:哪个进程利用CPU资源更多(不太准)
6.进程的上下文:保存上下文(读档),恢复上下文(存档)
7.进程的统计信息:统计每个进程在CPU上的运行时间和次数
进程的组织方式:
通过一个双向链表组织PCB
1.创建一个进程就是把PCB加入到链表中
2.销毁一个进程就是把PCB从链表中删除
3.查看所有的进程遍历是遍历双向链表
进程是操作系统中的一个核心单位
运行的程序在操作系统中以进程的形式存在
进程是分配资源的最小单位
2.内存分配 - 内存管理
程序运行时会分配内存空间
操作系统为了防止野指针,使用了虚拟内存来规避这个现象
通过内存管理单元(MMU)的方式来实现
3.进程中通信
目前,主流操作系统提供的进程通信机制有如下:
1.管道
2.共享内存
3.文件
4.网络
5.信号量
6.信号
4.多进程
多进程可以充分利用CPU资源区处理一些复杂的业力,从而提升业务的处理效率
串行:一个接一个的执行
并发:一会干这件事,一会干那件事
并行:一边干那件事,一边干那件事,真正意义上的同时执行
二、线程
1.什么是线程
通过多线程的方式可以提高程序处理任务的效率,创建线程的个数,根据CPU逻辑处理器的数据量来作为参考
2.线程的优势
1.线程的创建速度比进程快
2.线程的销毁速度比进程快
3.线程的CPU调度的速度比进程快
进程与进程之间,涉及的各种资源彼此之间不受影响,也就是说进程与进程之间之间是相互独立的
一个进程内线程之间是容易受到影响的
3.进程与线程的区别(常见面试题)
进程中包含线程,至少有一个主线程
进程是申请资源的最小单位
线程是CPU调度的最小单位
线程共享进程申请来的所有资源
一个线程如果崩溃了,就会影响整个进程
三、Java中的线程
1.如何用Java创建一个线程
线程:轻量级的进程,操作系统的概念
操作系统提供了一些API共程序员使用,每个操作系统提供的API都不同
API:(Application Programming Interface 应用程序编程接口)别人写好的一些函数方法,直接使用就行
Java对不同操作系统的API进行了封装
Thread类(标准库里的线程类)
2.第一个多线程程序
public class My_Thread {public static void main(String[] args) {//初始化自定义线程MyThread01 myThread01 = new MyThread01();//运行这个线程myThread01.start(); //启动线程,申请操作系统中的PCB,启动线程之后一个JAVA的Thread对象和 //操作系统中的PCB相对应}
}//自定义一个线程类,继承JDK中的Thread类
class MyThread01 extends Thread {@Overridepublic void run() {while (true) {//可以不停的处理任务System.out.println("hello my thread...");}}
}
1.操作系统中的PCB
2.JAVA中的线程,Thread类的一个对象,是对PCB的一个抽象
两者不是一个概念
JAVA创建一个线程对象 ---> JVM调用系统的API ----> 创建系统中的线程(参与CPU的调度)
package demo3;public class My_Thread02 {public static void main(String[] args) {//初始化自定义线程MyThread02 myThread02 = new MyThread02();//启动线程,创建PCB,参与CPU调度myThread02.start();//主线程中的任务while (true) {try {//休眠1000毫秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello main thread...");}}
}class MyThread02 extends Thread {@Overridepublic void run() {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("hello my thread...");}}
}
//两个死循环可以同时进行,互不干扰
线程的执行顺序并没有什么规律,这个和CPU的调度有关,由于CPU调度是 "抢占式" 执行的,所以哪个线程当前占用CPU资源是不确定的
3.用run()方法执行线程
public class My_Thread02 {public static void main(String[] args) {//初始化自定义线程MyThread02 myThread02 = new MyThread02();//启动线程,创建PCB,参与CPU调度
// myThread02.start();myThread02.run(); // 只是JAVA对象的一个方法而已//主线程中的任务while (true) {try {//休眠1000毫秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello main thread...");}}
}class MyThread02 extends Thread {@Overridepublic void run() {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("hello my thread...");}}
}
因为run()方法没有结束,程序只会卡在run()方法中
4.面试题
Thread类的start()和run()方法之间的区别:
1.start()方法,真实的申请系统线程PCB,从而开启一个线程,参与CPU调度
2.run()方法,定义线程时指定线程要执行的任务,如果调用,只是Java的一个普通方法而已
5.使用jConsole.exe查看JVM中线程的状态
6.创建线程的另一种方式(Runnable)
public class My_Thread03 {public static void main(String[] args) {//创建Runnable的实例MyRunnable01 myRunnable01 = new MyRunnable01();//创建线程Thread thread = new Thread(myRunnable01);//启动线程, 创建PCB, 参与CPU调度thread.start();//主线程中的任务while (true) {try {//休眠1000毫秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello main thread...");}}
}//单独定义了线程的任务 和线程类和业务解耦 让两行代码尽量分离,以便在后面修改代码的时候相互之间的 //影响最小化
class MyRunnable01 implements Runnable {// 实现具体的任务@Overridepublic void run() {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello my runnable...");}}
}
7.例子
需求:两条生产皮鞋的生产线,一双皮鞋2金币
一条生产皮鞋的生产线,一个皮鞋5金币
三个线程,两个任务
public class My_Thread04 {public static void main(String[] args) {//实例化任务对象MyRunnable01 myRunnable01 = new MyRunnable01(); // 皮屑MyRunnable02 myRunnable02 = new MyRunnable02(); // 皮包//创建线程对象Thread thread01 = new Thread(myRunnable01); // 皮鞋1Thread thread02 = new Thread(myRunnable01); // 皮鞋2Thread thread03 = new Thread(myRunnable02); // 皮包thread01.start();thread02.start();thread03.start();}
}class MyRunnable01 implements Runnable {@Overridepublic void run() {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("生产皮鞋 , 金币 + 2....");}}
}class MyRunnable02 implements Runnable {@Overridepublic void run() {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("生产皮包 , 金币 + 5....");}}
}
多个线程执行同一个任务就用Runnable的方式
如果中有一个线程,用Thread和Runnable都可以
8.通过创建Thread匿名内部类的方式创建线程
public class My_Thread05 {public static void main(String[] args) {Thread thread = new Thread() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("通过Thread匿名内部类的方式创建线程....");}};//启动线程thread.start();}
}
//通过Thread匿名内部类的方式创建线程....
9.通过创建Runnable接口的匿名内部类的方式来创建一个线程
public class My_Thread06 {public static void main(String[] args) {//匿名内部类, RunnableThread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("匿名内部类, Runnable....");}});// 启动线程thread.start();}
}
//匿名内部类, Runnable....
10.通过Lambda表达式创建一个线程(推荐方式)
public class My_Thread07 {public static void main(String[] args) {Thread thread = new Thread(() -> System.out.println("通过Lambda表达式创建线程...."));// 启动线程thread.start();}
}
//通过Lambda表达式创建线程....
四、多线程的优势
执行自增两轮10亿次
1.单线程
public class Text01 {//大数可以使用_分隔符private static long count = 10_0000_0000l;public static void main(String[] args) {//串行serial();}private static void serial() {// 记录开始时间long begin = System.currentTimeMillis();long a = 0l;for (int i = 0; i < count; i++) {a++;}long b = 0l;for (int i = 0; i < count; i++) {b++;}// 记录结束时间long end = System.currentTimeMillis();System.out.println("串行时间耗时:" + (end - begin));}
}
//串行时间耗时:591
2.分别两个线程
public class Text01 {//大数可以使用_分隔符private static long count = 10_0000_0000l;public static void main(String[] args) {//串行serial();//并行concurrency();}private static void concurrency() {//记录开始时间long begin = System.currentTimeMillis();//分别定义两个线程,各自执行累加操作//第一个线程Thread thread1 = new Thread(() -> {long a = 0l;for (long i = 0; i < count; i++) {a++;}});//启动thread1线程thread1.start();//第二个线程Thread thread2 = new Thread(() -> {long b = 0l;for (long i = 0; i < count; i++) {b++;}});//启动thread2线程thread2.start();//记录结束时间long end = System.currentTimeMillis();System.out.println("并行执行耗时:" + (end - begin));}private static void serial() {// 记录开始时间long begin = System.currentTimeMillis();long a = 0l;for (int i = 0; i < count; i++) {a++;}long b = 0l;for (int i = 0; i < count; i++) {b++;}// 记录结束时间long end = System.currentTimeMillis();System.out.println("串行时间耗时:" + (end - begin));}
}
//串行时间耗时:572
//并行执行耗时:0 (虚假的时间)
public class Text01 {//大数可以使用_分隔符private static long count = 10_0000_0000l;public static void main(String[] args) {//串行serial();//并行concurrency();}private static void concurrency() {//记录开始时间long begin = System.currentTimeMillis();//分别定义两个线程,各自执行累加操作//第一个线程Thread thread1 = new Thread(() -> {long a = 0l;for (long i = 0; i < count; i++) {a++;}});//启动thread1线程thread1.start();//第二个线程Thread thread2 = new Thread(() -> {long b = 0l;for (long i = 0; i < count; i++) {b++;}});//启动thread2线程thread2.start();//等待thread1和thread2执行完成try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}//记录结束时间long end = System.currentTimeMillis();System.out.println("并行执行耗时:" + (end - begin));}private static void serial() {// 记录开始时间long begin = System.currentTimeMillis();long a = 0l;for (int i = 0; i < count; i++) {a++;}long b = 0l;for (int i = 0; i < count; i++) {b++;}// 记录结束时间long end = System.currentTimeMillis();System.out.println("串行时间耗时:" + (end - begin));}
}
//串行时间耗时:575
//并行执行耗时:190
通过多线程可以明显提高效率,并行耗时是串行一半多一点的时间
并不是任何时候多线程的效率都要比单线程的效率要高,但任务量很少的时候,单线程的效率可能会比多线程更高(创建线程本身也会有一定的系统开销,这个开销没有创建进程的开销大 两个线程在CPU调度也需要一定的时间)
五、Thread类及常见的方法
1.Thread的常见构造方法
可以线程起一个名字,目的是为了程序员以后方便调度程序 (默认的线程名是thread-0,N>=0)
2.为线程起一个名字
public class Text02 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});//启动t1t1.start();//指定线程名Thread t2 = new Thread(() -> {while (true) {System.out.println("我是一个有名字的线程...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}, "我是一个线程");//启动t2t2.start();}
}
3.获取线程名
public class Text02 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (true) {//获取线程对象Thread thread = Thread.currentThread();System.out.println(thread.getName() + " hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();;}}});//启动t1t1.start();//指定线程名Thread t2 = new Thread(() -> {while (true) {//获取线程对象Thread thread = Thread.currentThread();System.out.println(thread.getName() + " 我是一个有名字的线程...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}, "我是一个线程");//启动t2t2.start();}
}
通过类 + 方法 + 线程的方式 可以明确记录某一个线程所产生的日志:
public class Text02 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (true) {//获取线程对象Thread thread = Thread.currentThread();System.out.println(thread.getName() + " hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});//启动t1
// t1.start();//指定线程名Thread t2 = new Thread(() -> {while (true) {//获取类名String cName = Text02.class.getName();//获取当前执行的方法名String mName = Thread.currentThread().getStackTrace()[1].getMethodName();//获取线程对象Thread thread = Thread.currentThread();//获取线程名String tName = thread.getName();// System.out.println(thread.getName() + " 我是一个有名字的线程...");System.out.println("当前类:" + cName + ", 当前方法:" + mName + ", 当前线程:" + tName);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}, "我是一个线程");//启动t2t2.start();}
}
//当前类:demo3.Text02, 当前方法:lambda$main$1, 当前线程:我是一个线程
//当前类:demo3.Text02, 当前方法:lambda$main$1, 当前线程:我是一个线程
//当前类:demo3.Text02, 当前方法:lambda$main$1, 当前线程:我是一个线程
//当前类:demo3.Text02, 当前方法:lambda$main$1, 当前线程:我是一个线程
//当前类:demo3.Text02, 当前方法:lambda$main$1, 当前线程:我是一个线程
//当前类:demo3.Text02, 当前方法:lambda$main$1, 当前线程:我是一个线程
4.Thread的几个常见属性
Thread是Java中的类 --> 创建的Thread对象 --> 调用start()方法 --> JVM调用系统API生成一个PCB --> 与Thread对象一一对应
Thread对象与PCB所处的环境不同,所以他们的生命周期也不同
public class Text03 {public static void main(String[] args) {Thread thread = new Thread(() -> {for (int i = 0; i < 10; i++) {try {System.out.println(Thread.currentThread().getName() + ": 我还活着");Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}}// 退出循环System.out.println(Thread.currentThread().getName() + ": 我即将死去");});System.out.println(thread.getName()+ ": ID: " + thread.getId());System.out.println(thread.getName()+ ": 名称: " + thread.getName());System.out.println(thread.getName()+ ": 状态: " + thread.getState());System.out.println(thread.getName()+ ": 优先级: " + thread.getPriority());System.out.println(thread.getName()+ ": 后台线程: " + thread.isDaemon());System.out.println(thread.getName()+ ": 活着: " + thread.isAlive());System.out.println(thread.getName()+ ": 被中断: " + thread.isInterrupted());// 启动线程,申请真正的PCB,参与CPU调度thread.start();while (thread.isAlive()) {
// System.out.println(Thread.currentThread().getName()
// + ": 状态: " + thread.getState());}System.out.println(thread.getName()+ ": 状态: " + thread.getState());}
}
//Thread-0: ID: 30 系统分配
//Thread-0: 名称: Thread-0
//Thread-0: 状态: NEW 线程对象已创建
//Thread-0: 优先级: 5 不太准
//Thread-0: 后台线程: false 不是后台,即前台
//Thread-0: 活着: false PCB已经销毁或者没有创建
//Thread-0: 被中断: false
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我还活着
//Thread-0: 我即将死去
//Thread-0: 状态: TERMINATED 线程结束
5.设置为后台进程
public class Text04 {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true) {System.out.println("hello thread...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});//设置为后台线程thread.setDaemon(true); // 注释掉程序就不会停止//启动thread.start();System.out.println("线程是否存活:" + thread.isAlive());System.out.println("main 方法执行完成");}
}
//hello thread...
//线程是否存活:true
//main 方法执行完成
设置为后台线程之后,main方法执行完成之后,整个程序就退出了,子程序也就自动结束了
如果是前台线程,子程序不会受main方法的影响,会一直运行下去
创建线程时默认是前台线程
前台线程可以阻止进程的进出
后台进程不阻止进程的退出
6.线程是否存活
public class Text05 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("hello thread...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程执行完成...");});System.out.println("启动之前查看线程是否存活:" + thread.isAlive());//启动线程thread.start();System.out.println("启动之后查看线程是否存活:" + thread.isAlive());//等待线程执行完成thread.join();//保证PCB已销毁Thread.sleep(1000);System.out.println("线程结束之后查看线程是否存活:" + thread.isAlive());}
}
//启动之前查看线程是否存活:false 还没创建PCB
//启动之后查看线程是否存活:true PCB存在
//hello thread...
//hello thread...
//hello thread...
//hello thread...
//hello thread...
//线程执行完成...
//线程结束之后查看线程是否存活:false PCB已销毁
7.线程中断
7.1通过共享的标记来进⾏沟通
自定义一个标志位,通过修改这个标志位,通知线程中断
中途可以通过用户的输入来发出信息
public class Text06 {// 自定义一个标志位static boolean isQuit = false; //提为全局变量public static void main(String[] args) throws InterruptedException {// final boolean isQuit = false;Thread thread = new Thread(() -> {while (!isQuit) { //lambda里面如果使用局部变量 触发“变量捕获”,// 如果出了main函数就会找不到 需要把变量定义为全局变量System.out.println("hello thread...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}//线程退出System.out.println("线程退出...");});// 启动线程thread.start();// 休眠5秒Thread.sleep(5000);// 修改标志位, 相当与发送信号isQuit = true;}
}
//hello thread...
//hello thread...
//hello thread...
//hello thread...
//hello thread...
//线程退出...
7.2调⽤ interrupt() ⽅法来通知
public class Text07 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {// 通过线程对象内部维护的中断标识,判断当前线程是否需要中断while (!Thread.currentThread().isInterrupted()) {// 线程中具体的任务是打印一句话System.out.println("hello thread...");// 线程大部分时间在sleeptry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程退出...");});System.out.println("启动之前查看线程是否存活:" + thread.isAlive());// 启动线程thread.start();// 休眠一会Thread.sleep(1000);System.out.println("启动之后查看线程是否存活:" + thread.isAlive());// 中断线程,发出中断信号thread.interrupt();// 等待线程销毁Thread.sleep(1000);// 查看线程是否存活System.out.println("线程结束之后查看线程是否存活:" + thread.isAlive());}
}
/*
启动之前查看线程是否存活:false 没有启动线程
hello thread... 线程启动,执行任务
hello thread...
启动之后查看线程是否存活:true 线程存活
hello thread...
java.lang.InterruptedException: sleep interrupted 中断线程时发现抛了个异常at java.base/java.lang.Thread.sleep0(Native Method)at java.base/java.lang.Thread.sleep(Thread.java:509)at demo3.Text07.lambda$main$0(Text07.java:10)at java.base/java.lang.Thread.run(Thread.java:1583)
hello thread...
线程结束之后查看线程是否存活:true PCB依然存在
hello thread... 任务继续执行
hello thread...
hello thread...
hello thread...
*/
当线程在sleep状态时,执行了中断操作,中断的是休眠状态的线程,就会抛出异常
1.sleep状态处理中断
public class Text07 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {// 通过线程对象内部维护的中断标识,判断当前线程是否需要中断while (!Thread.currentThread().isInterrupted()) {// 线程中具体的任务是打印一句话System.out.println("hello thread...");// 线程大部分时间在sleeptry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();// 休眠被中断System.out.println("休眠被中断...");// 处理中断逻辑break;}}System.out.println("线程退出...");});System.out.println("启动之前查看线程是否存活:" + thread.isAlive());// 启动线程thread.start();// 休眠一会Thread.sleep(1000);System.out.println("启动之后查看线程是否存活:" + thread.isAlive());// 中断线程,发出中断信号thread.interrupt();// 等待线程销毁Thread.sleep(1000);// 查看线程是否存活System.out.println("线程结束之后查看线程是否存活:" + thread.isAlive());}
}
/*
启动之前查看线程是否存活:false
hello thread...
hello thread...
启动之后查看线程是否存活:true
休眠被中断...
线程退出...
java.lang.InterruptedException: sleep interruptedat java.base/java.lang.Thread.sleep0(Native Method)at java.base/java.lang.Thread.sleep(Thread.java:509)at demo3.Text07.lambda$main$0(Text07.java:13)at java.base/java.lang.Thread.run(Thread.java:1583)
线程结束之后查看线程是否存活:false
*/
2.正常执行状态下中断线程
public class Text08 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {// 通过线程对象内部维护的中断标识,判断当前线程是否需要中断while (!Thread.currentThread().isInterrupted()) {// 线程中具体的任务是打印一句话System.out.println("hello thread...");}System.out.println("线程已退出");});System.out.println("线程是否存活:" + thread.isAlive());// 启动线程thread.start();System.out.println("线程是否存活:" + thread.isAlive());// 中断线程,发出中断信号thread.interrupt();// 等待线程销毁Thread.sleep(100);// 查看是否存活System.out.println("线程是否存活:" + thread.isAlive());}
}
/*
线程是否存活:false
线程是否存活:true
hello thread...
hello thread...
hello thread...
hello thread...
线程已退出
线程是否存活:false
*/
调用thread.interrupt();方法时
1.如果线程在运行状态,直接中断线程,不会报异常,符合程序预期
2.如果线程在等待状态,就会报一个终端异常,要在异常处理代码块中进行中断逻辑实现
8.等待一个线程
六.线程的状态
1.观察线程状态
public class Text01 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 10_0000_0000l; i++) {// 啥也不干}});// 启动之前看一下线程的状态System.out.println("启动之前:" + thread.getState());// 启动线程thread.start();// 启动之后线程的状态System.out.println("启动之后:" + thread.getState());// 等待线程执行完成thread.join();// 线程结束之后查看状态System.out.println("结束之后:" + thread.getState());}
}
/*
启动之前:NEW
启动之后:RUNNABLE
结束之后:TERMINATED
*/
public class Text01 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("hello thread...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});// 启动之前看一下线程的状态System.out.println("启动之前:" + thread.getState());// 启动线程thread.start();// 查看状态前等待一会TimeUnit.MILLISECONDS.sleep(500); //等待毫秒// 启动之后线程的状态System.out.println("启动之后:" + thread.getState());// 等待线程执行完成thread.join();// 线程结束之后查看状态System.out.println("结束之后:" + thread.getState());}
}
/*
启动之前:NEW
hello thread...
启动之后:TIMED_WAITING
hello thread...
hello thread...
hello thread...
hello thread...
结束之后:TERMINATED
*/
2.观察线程中所有的状态
/*** 查看JDK中Thread对象的所有状态*/public class Text02 {public static void main(String[] args) {//线程状态 定义在一个枚举当中for (Thread.State state : Thread.State.values()) {System.out.println(state);}}
}
/*
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
*/