JAVA-Thread类实现多线程

news2025/3/14 23:11:48

引言:

本章博客涉及进程线程内容,如果不了解的可以看:什么是进程线程-CSDN博客

 线程是操作系统的概念,操作系统提供的API供程序员使用操作。但是不同的操作系统(Winodws、Linux、Unix……差别很大),但是做为JAVA程序员就不需要担心了,JVM把这些封装好了。我们不需要关注系统原生API,只需要学习java提供的这一套API就可以了。

一、创建线程的几种方法

1.继承Thread类

//1.自己创建一个类,去继承 Thread类 并重写run方法
class MyThread extends Thread{
    //2.线程会自动调用run方法中的内容,类似主线程中的main方法
    @Override
    public void run() {
        while (true) {
            System.out.println("hello thread");
        }
    }
}


public class demo1 {
    public static void main(String[] args) {
        //3.实例化继承了Thread的类
        MyThread myThread = new MyThread();
        //4.创建线程
        myThread.start();

        while (true) {
            System.out.println("hello main");
        }
    }
}

结果就会不停打印:hello main  和 hello thread 

但是不方便观察而且,我电脑的风扇已经转起来了,因为相当于同时执行两个程序,并且死循环那么它的执行就非常的快。我们可以加上sleep(休眠),第一让线程休息指定时间,第二方便我们观察。

1.1 Thread.sleep()

传入的单位是毫秒(ms),sleep会让出CPU资源,不再争抢CPU资源

而且sleep还是静态的方法,我们直接使用类名调用。

sleep抛出异常问题:

如果是继承Thread的类,不能使用throws向上抛,因为Thread类中没有处理这个异常,我们只能使用try catch处理掉这个异常:

在主函数中的sleep:

在主函数中的sleep使用throws 和 try catch都是可以的,如果使用throwsJVM会处理这个异常,主函数中可以用 throws 处理 Thread.sleep() 方法抛出的 InterruptedException 异常,JVM 会处理这个被抛出的异常,具体表现为打印异常堆栈信息和终止程序执行。

//1.自己创建一个类,去继承 Thread类 并重写run方法
class MyThread extends Thread{
    //2.线程会自动调用run方法中的内容,类似主线程中的main方法
    @Override
    public void run() {
        while (true) {
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}


public class demo1 {
    public static void main(String[] args) throws InterruptedException {
        //3.实例化继承了Thread的类
        MyThread myThread1 = new MyThread();
        //4.创建线程
        myThread1.start();

        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

结果:

1.2 start()

start方法是创建线程的方法,底层会调用对应操作系统的API来创建线程。

1.3 run()

run()会被创建的线程自动调用,理解为另一个执行线程任务的入口,就像是JVM调用main方法一样。

2.实现Runnable接口

Thrad实现了Runnable接口:

Runnable接口是函数式接口,意味着我们还可以通过Lambda表达式来写。我们先用普通的方式写:

//1.定义一个类实现Runnable接口
class MyRunnable implements Runnable {
    //2.实现run方法
    @Override
    public void run() {
        while (true) {
            System.out.println("hello MyRunnable");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


public class demo2 {
    
    public static void main(String[] args) throws InterruptedException{
        //3.实例化实现Runnable的接口
        MyRunnable runnable = new MyRunnable();
        //4.把Runnable的接口给Thread
        Thread t = new Thread(runnable);
        //5.创建线程
        t.start();

        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }

    }
}

记得是先实例化实现Runnable的类,在实例化Thread类的时候,把实现了Runnable接口的类传入构造方法中。

结果:

为什么在Thread对象的时候可以传入Thread,肯定是有这样的一个构造方法,我们现在来了解一下Thread的构造方法。

2.1 Thread的构造方法

方法说明
Thread()创建线程对象
Thread(Runnable target)使用Runnable子类对象创建线程对象
Thread(String name)创建线程对象,并给线程取名字
Thread(Runnable target, String name)使用Runnable子类对象创建线程对象,并给线程命名
【了解】Thread(ThreadGroup group,Runnable target)线程可以被用来分组管理,分好的组即为线这个目前我们了解即可

 后面我会教两种方式观察线程,到时候就可以观察到,给线程的命名。

后面的实现多线程的本质都是上面两种方法。

3.使用匿名内部类来继承Thread类

本质就是第一种方法

public class demo3 {
    public static void main(String[] args) throws InterruptedException {
        //1.使用匿名内部类来继承Thread方法
        Thread t = new Thread() {
            //2.重写run方法
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello run");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        //3.创建线程
        t.start();

        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }


    }
}

结果:

4.在创建Thread对象的时候传入,实现Runnable的接口

 本质是第二种方法

public class demo4 {

    public static void main(String[] args) throws InterruptedException {
        //1.在创建Thread对象的时候,传入实现Runnable的匿名内部类
        Thread t = new Thread(new Runnable() {
            //2.重写run方法
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        //3.掉用线程
        t.start();

        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }

    }
}

5.Lambda表达式实现Runnable

不了解Lambda的可以看我这篇文章

JAVA-Lambda表达式(高质量)-CSDN博客

本质也是第二种方式

public class demo8 {

    public static void main(String[] args) throws InterruptedException {
        //1.实例化Thread对象时,传入实现了Runnable的匿名内部类
        Thread thread = new Thread(() -> {

            while (true) {
                System.out.println("hello Thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();

        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }


    }
}

结果:

更具第一种和第二种方式,其实还可以创建出好多种,这里就不一一举例了,每一种方式都很重要,都需要理解。 

二、观察线程

1.方式一

双击打开jconsole文件 ,程序必须是在运行的情况下

点击连接

选择不安全的连接

 选择线程

 用这个观察非常有用,以后程序多了就需要要用到这样的工具

2.方式二

打断点开始调试

 这里的线程默认命名也是Thread-?

 

如果我自己定义一个名字:

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

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

相关文章

【算法】DFS、BFS、拓扑排序

⭐️个人主页:小羊 ⭐️所属专栏:算法 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 持续更新中...1、DFS2、BFSN 叉树的层序遍历二叉树的锯齿形层序遍历二叉树最大宽度 3、多源BFS腐烂的苹果 4、拓扑排序 持续更新中…

MySQL中 IN 到底走不走索引?

文章目录 前言数据库表结构查询sqlEXPLAIN介绍EXPLAIN 的输出每列解释 强制走索引查询时添加条件(复合索引字段)查询小时查询分钟 总结 前言 在 MySQL 中,IN 语句是否能够利用索引取决于多个因素,包括但不限于查询的具体形式、表的统计信息、索引的选择…

centos没有ll

vi /etc/bashrc alias ll‘ls -l’ source /etc/bashrc

腾讯云低代码开发应用

创建客户端应用 如上所示,登录腾讯云微搭低代码业务控制台,开始搭建企业官网应用 如上所示,在腾讯云微搭低代码业务控制台中,开始创建企业官网应用 如上所示,在腾讯云微搭低代码业务控制台中,开始编辑企业官…

深度学习项目--基于DenseNet网络的“乳腺癌图像识别”,准确率90%+,pytorch复现

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 如果说最经典的神经网络,ResNet肯定是一个,从ResNet发布后,很多人做了修改,denseNet网络无疑是最成功的…

【Linux 指北】常用 Linux 指令汇总

第一章、常用基本指令 # 注意: # #表示管理员 # $表示普通用户 [rootlocalhost Practice]# 说明此处表示管理员01. ls 指令 语法: ls [选项][目录或文件] 功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件&#xf…

docker 搭建alpine下nginx1.26/mysql8.0/php7.4环境

docker 搭建alpine下nginx1.26/mysql8.0/php7.4环境 docker-compose.yml services:mysql-8.0:container_name: mysql-8.0image: mysql:8.0restart: always#ports:#- "3306:3306"volumes:- ./etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro- ./var/log…

Android7上移植I2C-tools

一,下载源码 cd hardware/libhardware/tests git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git 二, 在 i2c-tools 目录添加 Android.mk 编译文件 LOCAL_PATH: $(call my-dir)################### i2c-tools ###############…

Centos 7 修改语言和输入源为中文+修改终端快捷键复制为Ctrl+C、粘贴为Ctrl+V

目录 修改语言和输入源为中文 1、设置 2、Region & Language(区域和语言) 3、Add an Input Source(添加输入源) 4、修改语言为中文 5、Restart(重启) 6、Log Out (注销) …

DeepSeek-进阶版部署(Linux+GPU)

前面几个小节讲解的Win和Linux部署DeepSeek的比较简单的方法,而且采用的模型也是最小的,作为测试体验使用是没问题的。如果要在生产环境使用还是需要用到GPU来实现,下面我将以有一台带上GPU显卡的Linux机器来部署DeepSeek。这里还只是先体验单…

Python——计算机网络

一.ip 1.ip的定义 IP是“Internet Protocol”的缩写,即“互联网协议”。它是用于计算机网络通信的基础协议之一,属于TCP/IP协议族中的网络层协议。IP协议的主要功能是负责将数据包从源主机传输到目标主机,并确保数据能够在复杂的网络环境中正…

一招解决Pytorch GPU版本安装慢的问题

Pytorch是一个流行的深度学习框架,广泛应用于计算机视觉、自然语言处理等领域。安装Pytorch GPU版本可以充分利用GPU的并行计算能力,加速模型的训练和推理过程。接下来,我们将详细介绍如何在Windows操作系统上安装Pytorch GPU版本。 查看是否…

框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性

最近在思考一个问题:如何能够更好的分享主流框架源码学习笔记(主要是源码部分)?让有缘刷到的同学既可以有所收获,还能保持对相关技术架构探讨学习热情和兴趣。以及自己也保持较高的分享热情和动力。 今天尝试用一个SQL查询作为引…

ArrayList底层结构和源码分析笔记

参考视频:韩顺平Java集合 ArrayList特点 ArrayList 可以加入 null,包括多个。 ArrayList 是由数组来实现数据存储的 ArrayList 基本等同于 Vector,除了 ArrayList 是线程不安全(执行效率高)。在多线程情况下&#xf…

[内网渗透] 红日靶场2

环境配置 靶场地址: http://vulnstack.qiyuanxuetang.net/vuln/wiki/ 环境配置可以看这个: https://www.bilibili.com/video/BV1De4y1a7Ps/?spm_id_from333.337.search-card.all.click&vd_sourcecf73ac8de9b7c0322b1bccf77de91c5dNAT模式分配111段, DHCP也要更改 再添加…

MySQL 企业版 TDE加密后 测试和问题汇总

一、测试keyring file 1.1 当keyring file文件丢失或者被篡改 结论:不影响当前正在运行的数据库,但是在重启服务后会启动失败出现报错。 tail -n 100 /var/log/mysql/error.log 报错信息如下: 2025-03-12T08:04:54.668847Z 1 [ERROR] [M…

Unity 封装一个依赖于MonoBehaviour的计时器(下) 链式调用

[Unity] 封装一个依赖于MonoBehaviour的计时器(上)-CSDN博客 目录 1.加入等待间隔时间"永远执行方法 2.修改为支持链式调用 实现链式调用 管理"链式"调度顺序 3.测试 即时方法​编辑 "永久"方法 链式调用 ​4.总结 1.加入等待间隔时间&qu…

套接字缓冲区以及Net_device

基础网络模型图 一般网络设计分为三层架构和五层设计: 一、三层架构 用户空间的应用层 位于最上层,是用户直接使用的网络应用程序,如浏览器、邮件客户端、即时通讯软件等。这些程序通过系统调用(如 socket 接口)向内核…

2024下半年真题 系统架构设计师 案例分析

案例一 软件架构 关于人工智能系统的需求分析,给出十几个需求。 a.系统发生业务故障时,3秒内启动 XXX,属于可靠性 b.系统中的数据进行导出,要求在3秒内完成,属于可用性 c.质量属性描述,XXX,属…

c++介绍智能指针 十二(2)

智能指针share_ptr,与unique_ptr不同&#xff0c;多个shar_ptr对象可以共同管理一个指针&#xff0c;它们通过一个共同的引用计数器来管理指针。当一个智能指针对象销毁时&#xff0c;计数器减一。当计数器为0时&#xff0c;会将所指向的内存对象释放。 #include<memory>…