文章目录

  • 一、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常见属性

属性 获取方法
ID getId()
名称 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()方法。

Thread类及常见方法相关推荐

  1. 多线程的三种实现方法、线程类的常见方法、线程安全问题:synchronized和Lock锁、生产者和消费者问题

    1. 多线程的三种实现方式 1.1 继承Thread类 实现步骤: 定义一个类MyThread继承Thread类 在MyThread类中重写run()方法 创建MyThread类的对象 启动线程sta ...

  2. String类的常见方法的使用案例

    String类的常见方法的使用案例 //使用指定的字符串替换当前字符串中指定的内容//将helloworld中的o替换为aString s="HelloWorld";String ...

  3. P471String类的常见方法-P477StringBuffer的常见方法

    P471String类的常见方法-P477StringBuffer的常见方法 P471String类的常见方法 // 4.indexOf 获取字符在字符串对象中第一次出现的索引,索引从 0 开始,如果 ...

  4. Thread类的有关方法

    1.Thread类的有关方法 * 1.start():启动当前线程:调用当前线程的run()* 2.run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中* 3.cu ...

  5. 使用Thread类和Runnable方法来创建一个线程的区别

    第一:Thread类需要被继承,然后重写run()方法,但是Java中的类是单继承的,也就是说,若某个类继承Thread获取线程功能后,就不能再继承别的类了.但是Runnable接口解决了这个问题,某 ...

  6. python多线程返回值问题重写Thread类的run方法

    python多线程使用 文章目录 python多线程使用 一.案例 二.说明 1.针对第一种是有返回值的 ,可以通过future.result() 去拿到每个线程返回值 2.无返回值问题 3.我们可以 ...

  7. java面试题 Object类的常见方法总结

    /** native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写. */ public final native Class<?> getCl ...

  8. Java并发编程—Thread类的start()方法是如何启动一个线程的?

    目录 一:Java线程介绍 二:Java线程入口分析 三:Java线程的创建 四:总结 周末抽了点时间,研究了下HotSpot是如何创建Java线程的,顺便总结一下.文中引用的源码里删除很多细节,只保 ...

  9. java中scanner类的常见方法用法总结

    java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入. 首先要先创建一个Scanner对象. Scanner sc = new Scanner ...

最新文章

  1. Javascript基础系列之(三)数据类型 (数值 Number)
  2. C++多态:多态实现原理剖析,虚函数表,评价多态,常见问答与实战【C++多态】(55)
  3. 常用JavaScript语法107条
  4. Maven 系列 5:Maven 项目管理生命周期学习——命令界面四大指令完美运行 Hello、HelloFriend Java 项目完整步骤及错误总结
  5. python 持续集成方案_Jenkins+Python+GitLab持续集成
  6. linux和win10运行效率,Ubuntu与Win10周年版Ubuntu Bash性能对比
  7. indy9 indy10 MD5 实现方法
  8. 0基础lua学习(十八)C调用Lua----02Lua堆栈
  9. 解密车载语音识别架构 车载系统能听懂人说话?
  10. 记录php项目遇到502和504 Bad Gateway问题
  11. acdsee pro3 安装序列号
  12. kali下一键破解wifi密码
  13. 基于微信小程序的奶茶外卖商城系统设计与实现毕业设计毕设开题报告
  14. BS架构与CS架构的区别(最详细)
  15. 马来西亚留学回国人员证明
  16. 大型破碎设备之颚式破碎机简介
  17. Redis - Redis分布式算法原理——Hash一致性理解 Hash倾斜性解决方案
  18. 【Android】实现生成二维码、条形码和扫描二维码的功能
  19. 比较好用的CDN加速节点
  20. powerquery分组_Power Query中的Table.Group函数详细分析

热门文章

  1. 大恶人吉日嘎拉之走火入魔闭门造车之.NET疯狂架构经验分享系列之(三)商业逻辑代码部分
  2. 生产成本和销售成本的区别
  3. 天猫店群是什么意思,天猫店群是怎么赚钱的?优势都有哪些?
  4. 《程序开发心理学》读书笔记
  5. 改变浏览器URL不跳转 history.pushState
  6. 解决“本地计算机上的**服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止”
  7. android 软启动功能,软启动原理
  8. python为所欲为系列-制作游戏脚本
  9. shell中的环境变量设置
  10. emacs入门_Emacs入门