目录
9.通过创建Runnable接口的匿名内部类的方式来创建一个线程
一、进程
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 {
@Override
public 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 {
@Override
public 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 {
@Override
public 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 {
// 实现具体的任务
@Override
public 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); // 皮鞋1
Thread thread02 = new Thread(myRunnable01); // 皮鞋2
Thread thread03 = new Thread(myRunnable02); // 皮包
thread01.start();
thread02.start();
thread03.start();
}
}
class MyRunnable01 implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产皮鞋 , 金币 + 2....");
}
}
}
class MyRunnable02 implements Runnable {
@Override
public 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() {
@Override
public 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) {
//匿名内部类, Runnable
Thread thread = new Thread(new Runnable() {
@Override
public 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();
}
}
});
//启动t1
t1.start();
//指定线程名
Thread t2 = new Thread(() -> {
while (true) {
System.out.println("我是一个有名字的线程...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "我是一个线程");
//启动t2
t2.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();;
}
}
});
//启动t1
t1.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();
}
}
}, "我是一个线程");
//启动t2
t2.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();
}
}
}, "我是一个线程");
//启动t2
t2.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...");
// 线程大部分时间在sleep
try {
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...");
// 线程大部分时间在sleep
try {
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 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: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
*/