Java中几种常见的创建线程的方式

创建线程的几种方式

方法解释
Thread()创建线程对象
Thread(String name)创建线程对象,并给线程命名,不会影响线程
Thread(Runnable runnable)使用Runnable对象创建线程
Thread(Runnable runnable, String name)使用Runnable对象创建线程并给线程命名

方式1.创建一个类,继承Thread

每一个线程都是一个单独的”执行流“, 都可以执行一段代码逻辑,但是,线程是从哪里开始执行呢???就需要提供一个入口,而run方法就是线程的入口,表示就从run方法这里开始执行;

此时,我们写的一个Java程序其实就是一个进程,一个进程里面至少要有一个线程,就是主线程,而在Java程序中,主线程的入口方法就是main方法;

//创建一个类,继承Thread
class MyThread extends Thread{
    //重写Thread里面的run方法,这个方法就是线程的入口
    @Override
    public void run() {
        //代码逻辑
    }
}
public class Demo1 {
    public static void main(String[] args) {
        
    }
}

但是,只有run方法还是不够的,run方法只是线程执行的入口,只是说明了线程从哪个地方开始执行,run方法里面只是定义了线程要做哪些任务,需要在主线程中,调用 start() 方法来创建一个新的线程,线程创建后,线程就会调用run()方法开始执行任务。

代码如下:

//创建一个类,继承Thread
class MyThread extends Thread{
    //重写Thread里面的run方法,这个方法就是线程的入口
    @Override
    public void run() {
        System.out.println("线程正在工作");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
        //run() 和 start() 都是Thread的方法
        //run()方法只是线程的入口
        //start()方法才是调用了系统API来创建一个线程,让线程再调用run来执行任务
    }
}

在这里插入图片描述

下面演示一下两个线程并发执行的情况:

class MyThread extends Thread{
    //重写Thread里面的run方法,这个方法就是线程的入口
    @Override
    public void run() {
        //写一个while循环让这个线程一直打印
        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) throws InterruptedException {
        MyThread thread = new MyThread();
        thread.start();
        //写一个while循环,一直打印
        while(true) {
            System.out.println("hello main");
            //进行一个休眠方便观察
            Thread.sleep(1000);
        }
    }
}

在这里插入图片描述

上述结果就可以看到,两个线程分别在执行自己的代码,这也就印证了每一个线程都是一个单独的”执行流“, 本来在运行时只有一个执行流,但是遇见 thread.start() ,就开始了兵分两路”同时执行“, 就达到了并发编程的效果,而这里的并发指的是”并行+并发“, 因为,程序员在写代码的时候,是无法感知到这两个线程到底是在一个CPU核心上调度执行还是在两个CPU核心上同时执行, 所以在宏观上也就是我们人的肉眼看着都是在同时执行的,这一点在进程那篇文章中已经讲解的很清楚了。

如果将代码中的 thread.start() 改为 thread.run() 会发生什么呢?

在这里插入图片描述

如果改成thread.run(), 它就只剩下一个主线程了,只会按照代码的顺序依次执行,就变成了单独的方法调用,这就不是多线程了,只有当run()方法结束后,才会继续向下执行;也就没有实现”并发编程”;

在这里插入图片描述

方式2.创建一个类,实现Runnable接口

使用Runnable接口和继承Thread的区别就是为了解耦合,Runnable 就相当于是一个任务,在Runnable 中,也实现了 run() 方法,所以,就可以在Runnable 中写逻辑代码,然后,将这个Runnable 任务交给线程来执行。

代码如下:

//创建一个类,实现Runnable接口
class MyThread2 implements Runnable{
    @Override
    public void run() {
        while(true) {
            System.out.println("hello Thread");
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        //Runnable 就表示的是这是一个可执行的任务
        Runnable runnable = new MyThread();
        Thread thread = new Thread(runnable);
        
        thread.start();
        
        while(true) {
            System.out.println("hello main");
        }
    }
}

方式3.继承Thread,重写run(), 但是使用匿名内部类


    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("hello Thread");
            }
        };
        
        thread.start();
        System.out.println("hello main");
    }

方法4.实现Runnable,重写run(), 但是使用匿名内部类

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello Thread");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("hello main");
    }

方式5.使用Lambda表达式

    public static void main(String[] args) {
        
        Thread thread = new Thread(() -> {
            System.out.println("hello Thread");
        });

        thread.start();
        System.out.println("hello main");
    }

注意:上述这几种创建线程的方式只是一部分并非全部,创建线程有许多种方式,这几种比较简单而已,在多线程进阶中,还会再介绍几种创建线程的方式。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

直流电压变送器更改从站地址

直流电压变送器采集模块转RS485修改地址 产品图片 产品说明书 修改从站地址 在串口助手上将默认的从站地址01h修改为0Bh 原从站地址:01h 修改参数:10h 通信参数允许修改寄存器:1b fe(说明书里7166的十六进制) 00 02…

buuctf misc做题笔记

喵喵喵 使用stegsolve.jar,按BGR顺序提取出一个png图片,是一个只显示一半的二维码,修改图片高度显示全部二维码,解析出一个百度网盘地址,https://pan.baidu.com/s/1pLT2J4f 下载得到压缩包flag.rar。解压成功&#xf…

Vue开发实例(二)Vue代码运行及分析配置

Vue项目代码运行及分析 一、项目运行二、目录结构说明1、项目本身结构2、其他可能用到的文件夹 三、建议配置1、启动服务浏览器自动打开页面地址2、关闭eslint校验工具3、 src文件夹的别名的设置 一、项目运行 上篇文件末尾介绍到,进入项目,运行启动命令…

7.WEB渗透测试-Linux基础知识-Linux基础操作(一)

内容参考于: 易锦网校会员专享课 上一篇内容:5.WEB渗透测试-前置基础知识-常用的dos命令-CSDN博客 1.终端 终端:是一种特殊的字符设备,用来向计算机输入数据和显示计算机的输出 2.相对路径、绝对路径 绝对路径:cd/h…

怎么把人物从图中抠出?分享几种好用的抠图方法

在日常生活中,我们时常需要将人物从繁杂的背景中优雅地提取出来,无论是为了制作一张精美的证件照,还是为了设计一幅引人注目的海报或宣传画。然而,对于许多非专业人士来说,这仿佛是一场与细节的捉迷藏游戏,…

Web Tomcat

目录 1 前言2 Tomcat的安装3 Tomcat文件的构成4 Tomcat的使用步骤 1 前言 Tomcat是一个 http(web)的容器,笼统的理解一下所有的网站都叫做web。这个web容器可以把我们的前端(htmlcssjs)和后端(servlet)代码都运行起来。 Tomcat是一个免费的开源的Servlet容器&#…

鸿蒙Harmony应用开发—ArkTS声明式开发(触摸事件)

当手指在组件上按下、滑动、抬起时触发。 说明: 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 onTouch onTouch(event: (event: TouchEvent) > void) 手指触摸动作触发该回调。 卡片能力: 从…

STM32标准库开发——PWR电源控制

PWR简介 STM32内部供电方案 从图中可以看出VDD供电区域中有个电压调节器,可以降压到1.8V给CPU内部一些比较重要的设备供电,STM32内部不都是3.3V供电。另外还有低电压检测器,能够自动判断当前电压是否满足供电要求以此来灵活调节VBAT的供电电源…

13-Linux部署Kafka集群

Linux部署Kafka集群 简介 Kafka是一款分布式的、去中心化的、高吞吐低延迟、订阅模式的消息队列系统。 同RabbitMQ一样,Kafka也是消息队列。不过RabbitMQ多用于后端系统,因其更加专注于消息的延迟和容错。 Kafka多用于大数据体系,因其更加…

整数和浮点数在内存中的存储(大小端字节序,浮点数的存取)

目录 1.整数在内存中的存储 2.大小端字节序和字节序判断 2.1什么是大小端? 2.2为什么会有大小端 3.浮点数在内存中的存储 3.1浮点数的存储 3.1.1 浮点数存的过程 3.1.2 浮点数取的过程 3.2 解析 3.3 验证浮点数的存储方式 1.整数在内存中的存储 整数的二进…

Tomcat 部署和优化 (一)---------安装Oracle jdk 、tomcat

自 2017 年 11 月编程语言排行榜 Java 占比 13%,高居榜首,Tomcat 也一度成为 Java开发人员的首选。其开源、占用系统资源少、跨平台等特性被深受喜爱。本章主要学习如何部署 Tomcat 服务,根据生产环境实现多个虚拟主机的配置,最后…

『京墨』1.7.0 发布,开源的诗文(名句)、歇后语、成语、绕口令、节日等的阅读 APP

1.7.0 更新日志 优化 UI 显示;优化数据同步,尤其是诗文同步;【诗文名句】【成语】【歇后语】模块添加收藏功能;添加“滑动翻页”功能。 介绍 『京墨』开源的古诗词文(名句)、歇后语、成语、绕口令、节日…

C++/WinRT教程(第三篇)API的使用

目录 前言 Windows API 在WinRT中的投影 C/WinRT的头文件(投影标头) 通过对象、接口或通过 ABI 访问成员 投影类型的初始化方法 不要错误地使用延迟初始化 不要错误地使用复制构造 使用 winrt::make 进行构造 标准构造方法 在WinRT组件中实现A…

【Word如何在表格和标题中间插入一行】

目的:主要是为了满足文件设计需求,标题前面要空出一行 操作步骤: 1、将鼠标光标停在标题行的最前方,点击回车,就会在表格和标题中间插入一行空白标题行。 2、因为空白标题行会影响目录的生成,所以将空白行…

基于springboot+vue的实验室管理系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

对象的组合(java)

组合与复用 Circle类创建圆对象 Circle类创建圆锥对象,Circle类将Circle类声明的对象作为自己的一个成员 圆锥通过调用方法将某个圆的引用传递给圆锥的Circle类型的成员变量 package Absent;public class Chapter3 {public static void main(String[] args) {// …

jupyter 用pyecharts进行数据分析

一、jupyter和pyecharts下载和打开 因为我是用的pycharm,所以我直接在pycharm项目终端中下载pip install jupyter,pip install pyecharts 在你下载的项目路径中输入jupyter notebook 之后会进入页面 Jupyter 具体使用参考这个链接:Jupyter Notebook基本…

基于tomcat的JavaWeb实现

Tomcat服务器 免费,性能一般的服务器 安装配置 基于Java,故需要配置环境变量,新加系统路径JAVA_HOME,路径为jdk的主目录。 而后打开bin目录下的startup.bat文件出现如下窗口说明配置成功 idea继承tomcat服务器 使用java开发…

HCIA-Datacom实验指导手册:7 构建简单 IPv6 网络

HCIA-Datacom实验指导手册:7 构建简单 IPv6 网络 一、实验介绍:二、实验拓扑:三、实验目的:四、配置步骤:步骤 1 设备基础配置设备命名 步骤 2 配置设备及接口 IPv6 功能步骤 3 配置接口的 link-local 地址&#xff0c…

电脑数据丢失是什么原因 易我数据恢复软件下载 easyrecovery数据恢复软件下载 电脑数据删除了怎么恢复 电脑数据库损坏了怎么找回

目录 一、电脑数据丢失是什么原因 二、电脑数据丢失如何恢复 三、EasyRecovery恢复电脑数据的方法介绍 电脑是我们大家熟悉并且常用的数据存储设备,也是综合性非常强的数据处理设备。对于电脑设备来讲,最主要的数据存储介质是硬盘,电脑硬…