当前位置: 首页 > news >正文

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
*/

3.线程状态和状态转移的意义

相关文章:

  • Vue + Spring Boot 前后端交互实践:正确使用 `Content-Type: application/json` 及参数传递方式
  • SonarQube 25.6 完整指南:部署、使用与 CI/CD 集成
  • 【深度学习】TensorFlow全面指南:从核心概念到工业级应用
  • FPGA基础 -- Verilog语言要素之变量类型
  • JavaSE - Object 类详细讲解
  • C/C++中的位域(Bit-field)是什么?
  • 自然语言处理(NLP)核心技术:从词嵌入到Transformer
  • SSM框架:企业级Java开发利器
  • 【CUDA编程】OptionalCUDAGuard详解
  • 秋招是开发算法一起准备,还是只准备一个
  • 6.IK分词器拓展词库
  • 利用Tomcat本地部署Javaweb项目(windows)
  • 从CentOS迁移到TencentOS:9%成功率的一键替换实操
  • CppCon 2016 学习:The Exception Situation
  • Python编程基础
  • 计算机网络学习笔记:TCP流控、拥塞控制
  • 【QT】控件二(输入类控件、多元素控件、容器类控件与布局管理器)
  • 前端开发面试题总结-vue2框架篇(三)
  • 【6G技术探索】MCP协议整理分享
  • 黑马python(七)
  • 电白区住房和城乡建设部门户网站/搜狐酒业峰会
  • 江苏工程建设信息网站/网站注册步骤
  • 怎样申请网站域名/搜索引擎推广渠道
  • 政务网站建设 发言/百度浏览器网页版
  • 重庆建设工程信息网查询成绩分数/搜索引擎的优化和推广
  • 重庆商城网站制作报价/谷歌seo怎么优化