【多线程】Thread类的用法

文章目录

    • 1. Thread类的创建
      • 1.1 自己创建类继承Thread类
      • 1.2 实现Runnable接口
      • 1.3 使用匿名内部类创建Thread子类对象
      • 1.4 使用匿名内部类创建Runnable子类对象
      • 1.5 使用lambda创建
    • 2. Thread常见的构造方法
      • 2.1 Thread()
      • 2.2 Thread(Runnable target)
      • 2.3 Thread(String name)
      • 2.4 Thread(Runnable target, String name)
    • 3. Thread常见的属性
    • 4. 线程的使用
      • 4.1 启动线程
      • 4.2 中断线程
      • 4.3 等待线程
      • 4.4 休眠线程

1. Thread类的创建

1.1 自己创建类继承Thread类

package Thread;//继承Thread类实现线程
class MyThread extends Thread{@Overridepublic void run() {System.out.println("hello run");}
}
public class Dome1 {public static void main(String[] args){//创建线程MyThread myThread = new MyThread();//启动线程myThread.start();}
}

1.2 实现Runnable接口

//使用Runnable的方式创建线程
class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("hello run");}
} 
public class Dome2 {public static void main(String[] args){//创建线程MyRunnable myRunnable = new MyRunnable();Thread t = new Thread(myRunnable);//启动t.start();}
}

1.3 使用匿名内部类创建Thread子类对象

//通过匿名内部类的方式创建线程
public class Dome3 {public static void main(String[] args) {//创建线程Thread t = new Thread(){@Overridepublic void run() {System.out.println("hello run");}};//启动线程t.start();}
}

1.4 使用匿名内部类创建Runnable子类对象

//使用匿名内部类创建Runnable子类对象
public class Dome4 {public static void main(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("hello run");}});t.start();
}

1.5 使用lambda创建

//lambda实现线程
public class Dome5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread( () -> {System.out.println("hello run");});t.start();}
}

2. Thread常见的构造方法

2.1 Thread()

//创建Thread对象
Thread t = new Thread();

2.2 Thread(Runnable target)

//使用Runnable对象创建线程对象
Thread t = new Thread(new Runnable);

2.3 Thread(String name)

//为这个线程命名
Thread t = new Thread("名字");

2.4 Thread(Runnable target, String name)

//使用Runnable对象创建线程对象并命名
Thraed t = new Thread(new Runnable,"名字");

3. Thread常见的属性

属性获取方法
IDgetId()
namegetName()
状态getState()
优先级getPriority()
是否为后台线程isDaemon()
是否存活isAlive()
是否中断isInterrupted()
public class Test4 {public static void main(String[] args) {Thread t = new Thread(() -> {//Thread.currentThread调用当前线程对象,相当于t,这个时候t还未初始化成功,不能直接使用System.out.println("ID: " + Thread.currentThread().getId());System.out.println("name: " + Thread.currentThread().getName());System.out.println("状态: " + Thread.currentThread().getState());System.out.println("优先级: " + Thread.currentThread().getPriority());System.out.println("是否为后台线程: "  + Thread.currentThread().isDaemon());System.out.println("是否存活: " + Thread.currentThread().isAlive());System.out.println("是否中断: " + Thread.currentThread().isInterrupted());});t.start();}
}

运行结果1

注意:

  1. ID 是线程的唯一标识,不同线程不会重复
  2. 名称是各种调试工具用到
  3. 状态表示线程当前所处的一个情况,下面我们会进一步说明
  4. 优先级高的线程理论上来说更容易被调度到
  5. 关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。
  6. 是否存活,即简单的理解,为 run 方法是否运行结束了

4. 线程的使用

4.1 启动线程

前面我们已经知道了线程的创建,构造等方法,但这些其实都是准备工作,还没有真正的从底层创建出一个线程,只有调用start方法够才算真正的创建成功线程。
//直接调用就可以 t.start()

4.2 中断线程

当线程启动的时候,有时里面是循环,这时线程便不会停止,我们便要想办法中断线程。中断线程有个简单的方法直接使用Thread.stop()方法,但是,这种方法是unsafe,而且基本上已经deprecated。
所以我们调用interrupt()方法进行停止线程,但它并不会直接停止线程,而是对线程内进行标记,标记为Boolean类的true。这个时候我们再调用下面两个方法。
public static boolean interruputed();测试线程是否为中断状态,还执行后会标记清除为false。
public boolean isInterputed();测试线程是否为中断状态,但不清除标记。

添加标志符进行中断:

//中断线程,添加标志位
public class Test3 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {//while(!Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {
//                   e.printStackTrace();break;}}});//启动线程t1.start();//休眠3秒Thread.sleep(3000);t1.interrupt();}
}

注意:
如果休眠中中断线程,则会异常,反之,也是。

//中断线程,添加标志位
public class Test3 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {
//           while(!Thread.currentThread().isInterrupted()){try {Thread.sleep(100000);} catch (InterruptedException e) {e.printStackTrace();System.out.println("异常!");}
//           }System.out.println("end!");});t1.start();Thread.sleep(3000);t1.interrupt();System.out.println(t1.isInterrupted());System.out.println(Thread.interrupted());}
}

在这里插入图片描述

4.3 等待线程

方法说明
join()等待线程结束
join(long millis)等待线程结束,最多等待millis毫秒
join(long millis,int nanos)和2相比更加的精确

当我们同时启动几个线程,由于线程启动时随机无序的,我们无法得知谁先结束,这个时候就可以使用join方法让线程等待。

例如:当我们想让张三先上班,等张三上班结束,李四接班,那么我们就可以写出下面代码。

public class Test5 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (!Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName() + "在上班");try {Thread.sleep(1000);} catch (InterruptedException e ){break;}}},"张三");Thread t2 = new Thread(() -> {while(!Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName() + "在上班");try {Thread.sleep(1000);} catch (InterruptedException e) {break;}}},"李四");System.out.println("监督张三");t1.start();Thread.sleep(3000);t1.interrupt();t1.join();System.out.println("监督李四");t2.start();Thread.sleep(3000);t2.interrupt();t2.join();}
}

4.4 休眠线程

线程在执行的时候是非常快的,这个时候我们就可以让线程执行一次后就休眠一定时间,便于更好的观察。
上面代码中我们也多次用到。

Thread.sleep(long millis),里面millis单位是毫秒。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/86932.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ReactNative 密码生成器实战

效果展示图 使用插件 Formik 负责表单校验、监听表单提交、数据校验错误信息展示 Yup 负责表单校验规则 分析页面 从上述的展示图我们可以看到的主要元素有:输入框、单选按钮和按钮。其中生成的密码长度不可能很大也不可能为负数和 0,所以我们可以限…

VR智慧课堂 | 临床兽医学VR实验教学有哪些好处?

随着科技的不断发展,虚拟现实(VR)技术已经逐渐渗透到各个领域,为人们带来了前所未有的体验。在动物医学实验教学中,VR技术的应用也日益受到关注。本文将探讨临床兽医学VR实验教学的好处。 首先,VR技术能够提高动物医学实验的安全性…

跳跃游戏 II【贪心算法】

跳跃游戏 II class Solution {public int jump(int[] nums) {int cur 0;//当前最大覆盖路径int next 0;//下一步的最大覆盖路径int res 0;//存放结果&#xff0c;到达终点时最少的跳跃步数for (int i 0; i < nums.length; i) {//遍历数组&#xff0c;以给出数组以一个…

门禁系统忘记登入密码,现在更换电脑如何迁移旧电脑门禁系统的数据

环境&#xff1a; ivms-4200 v3.10.0.6_c 问题描述&#xff1a; 门禁系统忘记登入密码,现在更换电脑如何迁移旧电脑门禁系统的数据&#xff0c;旧电脑记住密码&#xff0c;忘了密码和密保了 解决方案&#xff1a; 1.前往海康官网下载4200客户端&#xff0c;在新电脑上安装 …

Python OCR 使用easyocr库将图片中的文章提取出来

Python OCR 使用easyocr库将图片中的文章提取出来 初环境内容步骤一&#xff1a;安装easyocr库步骤二&#xff1a;导入必要的库步骤三&#xff1a;创建OCR阅读器对象步骤四&#xff1a;指定要识别的图片路径步骤五&#xff1a;执行OCR识别并提取文章内容步骤六&#xff1a;遍历…

【Zblog搭建博客网站】windows环境搭建博客并上线

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员&#xff0c;自己搭建网站制作网页是绕…

『 LeetCode题解 』203. 移除链表元素

题目链接 : 『 LeetCode题解 』203. 移除链表元素 https://leetcode.cn/problems/remove-linked-list-elements/ 目录 &#x1f31f;题目要求&#x1f31f;解题思路&#xff08;动图解析&#xff09;&#x1f9d0;方案一&#x1f601;方案二 &#x1f31f;代码示列 &#x1f31…

第三方ipad笔哪个牌子好用?开学季ipad触控笔推荐

现在&#xff0c;对于ipad用户来说&#xff0c;苹果Pencil系列绝对是他们最好的选择。但价格太贵了&#xff0c;普通用户根本买不起。所以&#xff0c;在实际应用中&#xff0c;选择一种性能好&#xff0c;价格便宜的电容笔就显得尤为重要。身为一名“苹果粉”&#xff0c;又是…

C 连接MySQL8

Linux 安装MySQL 8 请参考文章&#xff1a;Docker 安装MySQL 8 详解 Visual Studio 2022 编写C 连接MySQL 8 C源码 #include <stdio.h> #include <mysql.h> int main(void) {MYSQL mysql; //数据库句柄MYSQL_RES* res; //查询结果集MYSQL_ROW row; //记录结…

使用WSL修改docker文件存储位置

按照以下说明将其重新定位到其他驱动器/目录&#xff0c;并保留所有现有的Docker数据。 首先&#xff0c;右键单击Docker Desktop图标关闭Docker桌面&#xff0c;然后选择退出Docker桌面&#xff0c;然后&#xff0c;打开命令提示符&#xff1a; wsl --list -v您应该能够看到&a…

c++冒泡排序的动画演示+程序实现

冒泡排序&#xff08;Bubble Sort&#xff09;是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果顺序&#xff08;如从大到小、首字母从Z到A&#xff09;错误就把他们交换过来。走访元素的工作是重复…