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

news2024/11/20 18:38:43

创建线程的几种方式

方法解释
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");
    }

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

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

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

相关文章

代码随想录训练营第31天 | 理论基础、LeetCode 455.分发饼干、

目录 理论基础 视频讲解:手把手带你学会操作链表 | 贪心算法理论基础!_哔哩哔哩_bilibili LeetCode 455.分发饼干 文章讲解:代码随想录(programmercarl.com) 视频讲解:贪心算法,你想先喂哪个小孩?| Le…

多线程万字详解

进程和线程是计算机程序执行的两个重要概念。 1.进程: 进程是操作系统分配资源的基本单位,每个进程都有自己独立的地址空间,每启动一个进程,系统就会为它分配内存。进程间通信比较复杂,需要用到IPC(InterP…

鸿蒙OS应用编程实战:构建未来应用的基石

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 引言 鸿蒙OS(HarmonyOS&#xff0…

大模型量化技术原理-SmoothQuant

近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。 模型压缩主要分…

老卫带你学---leetcode刷题(130. 被围绕的区域)

130. 被围绕的区域 问题 给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。 示例 1: 输入:board [[“X”,“X”,“X”,“X”]…

本届挑战赛亚军方案:基于大模型和多AGENT协同的运维

“轻舟已过万重山团队”荣获本届挑战赛亚军,该团队来自华为集团IT-UniAI 产品和openEuler系统智能团队。 方案介绍 自ChatGPT问世以来,AI迎来了奇点iPhone时刻,这一年来大模型深入影响企业办公,金融,广告,…

springboot+maven项目导入本地jar包,以有打包错误问题

1 本地jar包放置路径为: 2添加Modules File->project settings–>Modules–>Dependencies–>–>, 3 添加 Libraies 至此 项目即可成功运行。 mvn 打包错误,需要 运行以下命令 mvn install:install-file -Dfile${project.basedir}/s…

源码安装nginx保姆级教程

一.目录存放 1./usr/lib/syste,md/system/:每个服务最主要的启动脚本设定 2. /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先序要比 /usr/lib/systemd/system/ 高! 3./etc/systemd/system/:管…

c语言day4 运算符 表达式 三大控制结构

1: 2: 输入一个年月日 计算这是这一年的第几天 17 int year,month,day;18 printf("请输入年份 月份 日期");19 scanf("%d %d %d",&year,&month,&day);20 int feb28;21 if(year%40&&year%1…

AI大模型-启航

文章目录 什么是大模型?(大体现在参数量巨大)大模型将会改变那些行业(大模型有哪些作用?)如何搞数据训练模型?LangChain带来的技术变革LangChain架构 什么是大模型?(大体…

【深度学习笔记】深度卷积神经网络——NiN

网络中的网络(NiN) LeNet、AlexNet和VGG都有一个共同的设计模式:通过一系列的卷积层与汇聚层来提取空间结构特征;然后通过全连接层对特征的表征进行处理。 AlexNet和VGG对LeNet的改进主要在于如何扩大和加深这两个模块。 或者&am…

Linux中如何在创建子线程的时候设置为分离属性

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> #include <pthread.h> void *mythread(void *arg) {printf("id[%ld]\n",pthread_self()); } int main() { //定义pthread_…

【Java程序设计】【C00324】基于Springboot的高校疫情防控管理系统(有论文)

基于Springboot的高校疫情防控管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校疫情防控系统&#xff0c;本系统有管理员、学校管理员、学院管理员、教师以及学生五种角色&#xff1b; 管理员&#x…

camunda7流程引擎外部任务(External Task)如何使用

camunda7流程引擎支持两种执行服务任务的方式: 内部任务&#xff1a;同步调用与流程应用程序一起部署的代码外部任务&#xff1a;在列表中提供可由员工轮询的工作单元 第一个选项可以通过委托代码&#xff08;Delegation&#xff09; 或者脚本&#xff08;Script&#xff09;…

从零开始手写RPC框架(1)

学习java后端也有一段时间了&#xff0c;在网上寻一些教程和github上的开源库&#xff0c;学习从零开始手写一个RPC&#xff0c;学习各位大牛的代码适当修改&#xff0c;并贴上自己的一些见解和注释。 目录 RPC简介RPC和HttpClient的区别和共同点常见RPC框架 RPC框架设计常见序…

白宫敦促开发者弃用C和C++,转而使用“内存安全”的编程语言。

美国白宫国家网络总监办公室&#xff08;ONCD&#xff09;在一份新报告中呼吁开发者停止使用C或C等编程语言&#xff0c;转而使用“内存安全编程语言”&#xff0c;这是美国总统拜登网络安全战略的一部分&#xff0c;旨在保护网络空间的基础构建块。内存安全是指防止因内存访问…

6.WEB渗透测试-前置基础知识-AI应用

内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;5.WEB渗透测试-前置基础知识-常用的dos命令-CSDN博客 1.AI在生活中扮演的角色越来越重要&#xff0c;AI现在可以用来帮我们办许多事情 目前比较好用的AI模型例如Chatgpt&#xff0c;Claude&#xff0c;必应…

推荐一款ssh工具 xshell替代品 electerm

下载地址 electerm&#xff1a; https://electerm.github.io/electerm/ windows版本 产品优势 复制粘贴&#xff0c;可以直接使用ctrlc/v 非常的方便 而且不想xshell 需要账号登陆&#xff0c;有更新弹窗&#xff0c;自身集成了sftp 界面设计更新&#xff0c;比MobaXterm的…

TCP的三次握手和四次挥手 | 查看网络状态

三次握手和四次挥手是在计算机网络中用于建立和终止TCP连接的协议。这两个过程是TCP协议的重要组成部分&#xff0c;确保数据的可靠传输。 三次握手指的是在客户端和服务器之间建立连接时的步骤。具体流程如下&#xff1a; 客户端向服务器发送一个连接请求报文段&#xff08;…

0201sherlock(福尔摩斯)-通过名称寻找媒体账号(地址)-github-开源项目学习

文章目录 一 项目简介二 项目安装和演示1 安装2 演示 三 源码分析1 项目结构2 主程序源代码分析 四 添加自定义网址结语 一 项目简介 二 项目安装和演示 1 安装 # clone the repo $ git clone https://github.com/sherlock-project/sherlock.git# change the working direct…