Thread类及常见方法
创始人
2024-04-20 20:30:38
0

在这里插入图片描述

文章目录

  • 一、Thread常见构造方法
  • 二、Thread常见属性
  • 三、Thread常见方法
    • start()
    • 获取当前线程
    • 休眠当前线程
    • 中断线程
    • join()

一、Thread常见构造方法

Thread类是JVM用来管理线程的一个类,每个线程都有唯一一个Thread对象与之对应,JVM会将这些对象组织起来,线程调度,线程管理。
在这里插入图片描述

方法说明
Thread()创建线程对象
Thread(Runnable target使用Runnable对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target,String name)使用Runnable对象创建线程,并命名

我们在创建Thread的对象为什么要命名?方便我们查看信息和调试。
在这里插入图片描述
线程默认名叫做Thread-0, Thread-1等等,当线程比较多的时候,很难分辨线程,所以我们可以命名。

二、Thread常见属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否有后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

getId(): ID是线程的唯一标识,不同的线程不重复

class MyThread extends Thread{@Overridepublic void run() {System.out.println("Hello world!");}
}
public class ThreadDemo {public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.getId());}
}

在这里插入图片描述

getName: 名称是我们构造方法设置的名称,如果没有设置,那就是默认名。

public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.getName());}

在这里插入图片描述
因为我们没有命名,所以使用的是默认名。
getState(): 指的是当前线程所处的状态 ( java当中的线程状态比操作系统中的状态更丰富,分的更细 ).

public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.getState());}

在这里插入图片描述
这里NEW状态 (指的是线程对象已创建,但操作系统还没有为其分配PCB) 是什么大家先不用管,后面我们会详细介绍,只需要知道getState()方法是用来查看线程状态的。
getPriority: 我们可以获取当前线程的优先级,但没有太大的用,实际还得取决于操作系统内核的具体调度。

public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.getPriority());}

在这里插入图片描述
isDaemon(): 是否为守护线程(也叫后台线程), 简单的理解一下,我们手动创建的线程都是前台线程,JVM自带的线程都是后台线程,我们也可以通过setDaemon()方法将前台线程设置为后台线程。
在这里插入图片描述

public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.isDaemon());}

在这里插入图片描述
isAlive(): 线程的run方法是否执行结束。
在这里插入图片描述

如果我们只创建了一个t变量,我们并没有在操作系统内核里有线程,只是把我们线程执行的任务梳理好了
在这里插入图片描述
当我们执行了start()方法后,就会让内核创建一个PCB,此时这个PCB才表示一个真正的线程。
调用start()方法之前,isAlive()是false
调用start()方法之后,run()方法未执行完,isAlive()为false.

public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.isAlive());t.start();System.out.println(t.isAlive());}

在这里插入图片描述

**isInterrupt(): ** 线程中断问题
这两个方法我们后面会进一步说明。

三、Thread常见方法

start()

start() 启动一个线程。

class MyThread extends Thread{@Overridepublic void run() {System.out.println("Hello world!");}
}
public class ThreadDemo {public static void main(String[] args) {Thread t = new MyThread();t.start();}

在这里插入图片描述
run()方法提供线程要做的事情的指令清单。
在这里插入图片描述
这是创建t对象,只是知道要找那样的线程做什么事
在这里插入图片描述
只有当start(),操作系统内核才会创建一个真真正正的线程PCB,然后去调用run()方法。

获取当前线程

方法说明
currentThread()获取当前线程对象的引用

在这里插入图片描述
我们可以发现currentThread()方法是Thread类下的一个静态方法,所以我们直接使用类名调用即可。

休眠当前线程

方法说明
sleep(long millis)休眠当前线程millis毫秒

由于线程调度是不可控的,我们sleep()方法的实际休眠是大于等于设置的时间的。

在这里插入图片描述
我们的sleep方法也是Thread下的静态方法,直接类名调用即可。
需要注意的是我们在那个线程下面调用该方法,那个线程休眠。
在这里插入图片描述
使用sleep时会有一个中断异常(非受查异常),需要我们手动抛出。

public static void main(String[] args) throws InterruptedException {System.out.println(System.currentTimeMillis());Thread.sleep(1000);System.out.println(System.currentTimeMillis());}

我们直接在主线程演示一下该方法。
在这里插入图片描述

中断线程

线程中断: 我们这里的中断,并不是线程立即就结束了,而是通知该线程,你应该结束了,但实际是否结束,取决于线程里具体的代码。
1.使用标志位来控制线程是否结束

public class ThreadDemo {private static boolean flg = true;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (flg) {System.out.println("My Thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();Thread.sleep(3000);flg = false;}
}    

在这里插入图片描述
在这里插入图片描述
我们这个代码之所以能够起到修改flg就使线程结束,完全取决于线程内部的代码书写,我们只能起到一个通知作用,至于是否结束,还是取决于线程内部,即使我们sleep正在休眠,我们的标志位也可以唤醒sleep。

2. 调用 interrupt() 方法来通知

public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println("My Thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();Thread.sleep(3000);t.interrupt();}

在这里插入图片描述
在这里插入图片描述
我们可以发现我们的代码触发了异常。
在这里插入图片描述
在唤醒sleep之后,我们的线程还在一直执行
在这里插入图片描述
interrupt()方法会做两件事:
1.把线程内部的标志位设置为true
2.如果线程正在sleep,会触发异常,将sleep唤醒。
sleep唤醒的同时,会清空标志位,将刚才设置的标志位在设置为false(这就导致,我们的循环会继续执行).
如果我们想去中断,我们可以在异常里加一个break。当我们sleep被唤醒时,结束run()方法。
在这里插入图片描述
在这里插入图片描述

这里再一次证明了,这里的中断只是通知线程,至于是否执行还得看线程内部的代码。

join()

join(): 等待一个线程
因为我们线程是随即调度的过程,线程的执行顺便我们无法把控,但在一些场景下我们需要有明确的线程程序顺序,等待线程,就是可以控制两个线程的结束顺序。

方法说明
join()等待线程结束
join(long millis)等待线程结束,最多等millis毫秒
public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("My Thread!");}});t.start();System.out.println("Main!");}

在这里插入图片描述
我们想让t线程先执行完,再去打印Main!

public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("My Thread!");}});t.start();t.join();System.out.println("Main!");}

在这里插入图片描述
我们在主线程调用了下join()方法。
在这里插入图片描述

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...