Thread类的基本用法

1.线程创建

这里介绍线程创建常用的五种方法

 1.继承Thread,重写run

class MyThread extends Thread{public void run(){//这里写的代码就是线程要完成的任务while (true){System.out.println("hello thread");try {Thread.sleep(1000);//线程会休眠一秒再执行,不休眠会执行得很快} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class Demo1 {public static void main(String[] args) {Thread t=new MyThread();// 没有创建出新的线程, 就是在主线程中执行上述 run 中的循环打印.//t.start();//hello thread 和 hello main 并发执行t.run();//只有 hello threadwhile(true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

start 和 run这两个方法的区别是什么呢?

作用功能不同:

  1. run方法的作用是描述线程具体要执行的任务;
  2. start方法的作用是真正的去申请系统线程

运行结果不同:

  1. run方法是一个类中的普通方法,主动调用和调用普通方法一样,会顺序执行一次;
  2. start调用方法后, start方法内部会调用Java 本地方法(封装了对系统底层的调用)真正的启动线程,并执行run方法中的代码,run 方法执行完成后线程进入销毁阶段。

调用start方法:                                                调用run方法:

                       

2.重写Runnable方法,重写run,把Runnable实例传入到Thread中

class MyRunnable implements Runnable{public void run(){while (true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class Demo2 {public static void main(String[] args) {Thread t=new Thread(new MyRunnable());t.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

3.针对 1的变形,使用匿名内部类, 继承 Thread 并重写 run.

public class Demo3 {public static void main(String[] args) {Thread t=new Thread(){public void run(){while (true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};t.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}

4.实现 Runnable, 重写 run, 使用匿名内部类

public class Demo4 {public static void main(String[] args) {Thread t=new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});t.start();while (true){System.out.println("hello main");try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

5.使用 lambda 表达式

public class Demo5 {public static void main(String[] args) {Thread t=new Thread(() -> {while (true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}

上述每种方法执行的结果都是大同小异,就是hello main和hello thread 并发执行,并且是抢占式执行,你也不知道hello thread 的下一句还是hello thread 或者是hello main。

2.线程中断

 线程运行起来之后如果想要中断,就需要采用interrupt()方法来中断

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

3.线程等待

有时,我们需要等待⼀个线程完成它的⼯作后,才能进行自己的下⼀步⼯作。

    public static void main(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {while (true){System.out.println("1");}}});t.start();while(true){System.out.println("2");}}

 由于上述代码中main 和 t线程 之间的结束顺序是不确定的,如果希望让代码里面的 t能够先结束main 后结束,就可以在 main 中使用线程等待(join)

这个方法有三种,每种功能不一样

方法说明
public void join()等待线程结束(死等)
public void join(long millis)等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)同理,但可以更高精度
  public static void main(String[] args) throws InterruptedException {Thread t = new Thread(new Runnable() {@Overridepublic void run() {while (true){System.out.println("1");}}});t.start();t.join();while(true){System.out.println("2");}}

 main 中线程调用 t.join 就是让 main 线程被阻塞并等待t线程.

由于这个代码调用的是死等的那个join方法,就会导致main线程陷入无尽等待一直无法执行,只有t线程执行,结果就是一直只有1。

如果用其余两个方法,那么结果就是main线程会先等待t线程执行一段时间后再开始执行。

4.线程休眠

方法说明
public static void sleep(long millis) throws InterruptedException让当前线程休眠一定时间
public static void sleep(long millis, int nanos) throws InterruptedException让线程休眠一定时间(时间精度更高)

 前面的代码执行的时候我们会发现线程执行的速度很快,让线程休眠可以更好地看到线程执行的过程。

public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()->{while (true){System.out.println("tjc");try {Thread.sleep(2000);//t线程会休眠两秒再执行} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();while (true){System.out.println("hs");Thread.sleep(2000);//main线程会休眠两秒执行}
}

5.获取线程实例

方法说明
 public static Thread currentThread();返回当前线程对象的引用
    public static void main(String[] args) {Thread thread = Thread.currentThread();System.out.println(thread.getName());}

得到的是main线程的实例

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

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

相关文章

二维码门楼牌管理应用平台建设:取保候审人员管理的新模式

文章目录 前言一、取保候审人员管理的新挑战二、二维码门楼牌管理应用平台的引入三、平台的功能与应用四、优势与挑战五、结论 前言 随着科技的不断进步,二维码门楼牌管理应用平台已成为城市管理的创新手段。特别是在取保候审人员管理领域,这一技术的应…

电视盒子哪款好?实体店主盘点畅销电视盒子排名

电视盒子功能丰富,是升级电视机最具性价比的方案。我本人做实体数码店多年来,电视盒子是店内销量最好的产品之一,最近很多网友在讨论电视盒子哪款好,我整理了店内销量最好的电视盒子排名,想买电视盒子可以看看下面这几…

海外盲盒App开发:探索全球惊喜,开启无限可能

一、前言 随着全球化的深入发展,人们对于不同文化、不同地域的商品充满了好奇与向往。盲盒文化,作为一种充满神秘与惊喜的消费方式,正逐渐在全球范围内受到热烈追捧。为了满足海外用户对于盲盒的需求,我们团队精心策划并开发了一…

读写锁ReentrantReadWriteLockStampLock详解

现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁(读多写少)。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源(读读…

盲人安全过马路:科技赋能,独立出行不再难

作为一位资深记者,我长期关注特殊群体的生活现状与科技助力下的改善举措。今天,我要讲述的是盲人朋友在独立出行,尤其是过马路时面临的挑战,以及一款叫做蝙蝠避障的创新辅助应用如何通过实时避障与拍照识别功能,显著提…

深入解读Dubbo:微服务RPC框架的佼佼者

在微服务盛行的今天,RPC(远程过程调用)框架的重要性日益凸显。Dubbo,作为阿里巴巴公司开源的一款高性能、轻量级的Java RPC框架,已经成为众多企业构建微服务架构的首选。作为一名资深的架构师,我深知Dubbo在…

IntelliJ IDEA 如何启用 JDK 预览特性

IntelliJ IDEA 也可以启用 JDK 的预览特性。 针对项目,选择项目结构。 配置是在语言结构上。 单击语言结构上的 SDK 默认,往下拉,就可以看到针对新版本的选项。 同时还可以看到那些版本是支持新特性预览的,那些版本是不支持新特…

Vue报错 Cannot read properties of undefined (reading ‘websiteDomains‘) 解决办法

浏览器控制台如下报错: Unchecked runtime.lastError: The message port closed before a response was received. Uncaught (in promise) TypeError: Cannot read properties of undefined (reading websiteDomains) at xl-content.js:1:100558 此问题困扰了…

多目标粒子群算法及其MATLAB实现

多目标粒子群优化(Multi-Objective Particle Swarm Optimization, MOPSO)算法是一种基于种群的优化算法,它结合了粒子群优化(Particle Swarm Optimization, PSO)和多目标优化的思想。多目标粒子群(MOPSO&am…

PCL:投影滤波器

1.介绍 在点云处理中,投影滤波器是一种常用的工具,它可以将点云投影到给定的模型上,并保留投影后的点云数据。 投影滤波器主要应用于以下场景: 平面投影:将点云投影到一个已知的平面上,以获取平面上的点云数据。几何模型投影:将点云投影到已知的几何模型上,如圆柱体、…

IP地址信息——IP地址、子网掩码、默认网关和DNS

IP地址信息 通常来说,一个完整的IP地址信息应该包括IP地址、子网掩码、默认网关和DNS等4部分内容,只有当它们各司其职、协同工作时,我们才可以访问Internet,并被Internet中的计算机所访问。需要注意的是,采用静态IP地…

开发工具-pycharm的代码自动部署服务器以及服务端python配置、项目开发环境一键启动服务

文章目录 一、pycharm的ssh配置1.本地生成ssh密钥2.密钥配置到远端服务器(1-1) 有权限ssh访问到服务器(1-2) 无权限ssh访问到服务器(1-3) 没有办法通过以上形式上传到服务器(2) 配置到authorized_keys自动访问 3.pycharm中配置ssh(1) 选择File中的settings(1) 选择Tools中的SSH…

在 React Router v5 中,写子路由,父级路由如果加了exact属性,就显示不了子组件

在 React Router v5 中,当你在父级路由上使用 exact 属性时,它意味着该路由只有在其 path 完全匹配当前 URL 时才会被激活。这意味着,如果父级路由精确匹配了,React Router 就不会继续向下查找子路由,因为 exact 限制了…

js的算法-插入排序(折半插入排序)

直接插入排序的步骤 1. 从前面的有序子表中查找出待插入元素应该被插入的位置 2. 给插入位置腾空间 3. 将待插入元素复制到表中的插入位置。 直接插入排序:边比较边移动; 折半插入排序 先折半查找出元素的待插入位置,然后统一地移动待插…

上位机图像处理和嵌入式模块部署(树莓派4b之远程vnc桌面访问)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 对于很多嵌入式开发比较精通的同学来说,使用命令行和开发板之间进行沟通是他们完全能够接受的一种开发方式。但是对于更多的朋友来说&a…

AI编码prompt编写及内在逻辑

最近在做一个项目,涉及AI编码表和标准码表。那么什么AI编码表,什么是标准码表,AI编码表生成的逻辑是什么呢? 文章目录 1. 什么是AI编码表,什么是标准码表?2. AI编码码表的生成逻辑是怎么样的?3.…

0425DormAJAX项目

0425DormAJAX项目包-CSDN博客 数据库字段 添加界面: 初始状态: 点击性别,宿舍号使用ajax动态添加: 学生主界面: 实现分页查询: 点击修改学生宿舍,查看换寝记录,ajax动态显示列表&…

【设计模式】发布订阅模式,构建可以接收历史消息的观察者类

什么是发布订阅模式? 发布订阅模式也被称为观察者模式,这个模式中有两种角色:发布者(被观察者) 和 订阅者(观察者)。 通常的操作是:订阅者订阅发布者的某一个事件,发布…

C语言例题29:在屏幕上显示一个等腰三角形

#include <stdio.h>void main() {int i, j;int x;printf("输入等腰三角形行数&#xff1a;");scanf("%d", &x);for (i 1; i < x; i) {for (j i; j < x; j) {printf(" "); //输出空格占位}for (j 1; j < 2 * i; j) {printf…

接字符串注入攻击简介

连接字符串注入攻击简介 什么是连接字符串注入攻击&#xff1f; 连接字符串注入攻击是一种安全攻击类型&#xff0c;攻击者通过修改应用程序使用的数据库连接字符串来注入恶意内容。连接字符串是包含数据库连接所需数据&#xff08;如服务器地址、数据库名、用户名和密码等&a…