创建和启动线程

 概述

  • Java语言的JVM允许程序运行多个线程,使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。

  • Thread类的特性

    • 每个线程都是通过某个特定Thread对象的run()方法来完成操作的,因此把run()方法体称为线程执行体

    • 通过该Thread对象的start()方法来启动这个线程,而非直接调用run()

    • 要想实现多线程,必须在主线程中创建新的线程对象。

方式1:继承Thread类

Java通过继承Thread类来创建启动多线程的步骤如下:

  1. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务

  2. 创建Thread子类的实例,即创建了线程对象

  3. 调用线程对象的start()方法来启动该线程

代码如下:

package com.atguigu.thread;
//自定义线程类
public class MyThread extends Thread {
    //定义指定线程名称的构造方法
    public MyThread(String name) {
        //调用父类的String参数的构造方法,指定线程的名称
        super(name);
    }
    /**
     * 重写run方法,完成该线程执行的逻辑
     */
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+":正在执行!"+i);
        }
    }
}

测试类:

package com.atguigu.thread;

public class TestMyThread {
    public static void main(String[] args) {
        //创建自定义线程对象1
        MyThread mt1 = new MyThread("子线程1");
        //开启子线程1
        mt1.start();
        
        //创建自定义线程对象2
        MyThread mt2 = new MyThread("子线程2");
        //开启子线程2
        mt2.start();
        
        //在主方法中执行for循环
        for (int i = 0; i < 10; i++) {
            System.out.println("main线程!"+i);
        }
    }
}
 

 

注意:

  1. 如果自己手动调用run()方法,那么就只是普通方法,没有启动多线程模式。

  2. run()方法由JVM调用,什么时候调用,执行的过程控制都有操作系统的CPU调度决定。

  3. 想要启动多线程,必须调用start方法。

  4. 一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出以上的异常“IllegalThreadStateException”。

 方式2:实现Runnable接口

Java有单继承的限制,当我们无法继承Thread类时,那么该如何做呢?在核心类库中提供了Runnable接口,我们可以实现Runnable接口,重写run()方法,然后再通过Thread类的对象代理启动和执行我们的线程体run()方法

步骤如下:

  1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

  2. 创建Runnable实现类的实例,并以此实例作为Thread的target参数来创建Thread对象,该Thread对象才是真正 的线程对象。

  3. 调用线程对象的start()方法,启动线程。调用Runnable接口实现类的run方法。

代码如下:

package com.atguigu.thread;

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

测试类:

package com.atguigu.thread;

public class TestMyRunnable {
    public static void main(String[] args) {
        //创建自定义类对象  线程任务对象
        MyRunnable mr = new MyRunnable();
        //创建线程对象
        Thread t = new Thread(mr, "长江");
        t.start();
        for (int i = 0; i < 20; i++) {
            System.out.println("黄河 " + i);
        }
    }
}

 

 

通过实现Runnable接口,使得该类有了多线程类的特征。所有的分线程要执行的代码都在run方法里面。

在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。

实际上,所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是继承Thread类还是实现 Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程编程的基础。

说明:Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。 而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

 变形写法

使用匿名内部类对象来实现线程的创建和启动

new Thread("新的线程!"){
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+":正在执行!"+i);
        }
    }
}.start(); 

new Thread(new Runnable(){
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+":" + i);
        }
    }
}).start(); 

 对比两种方式

联系

Thread类实际上也是实现了Runnable接口的类。即:

public class Thread extends Object implements Runnable 

区别

  • 继承Thread:线程代码存放Thread子类run方法中。

  • 实现Runnable:线程代码存在接口的子类的run方法。

实现Runnable接口比继承Thread类所具有的优势

  • 避免了单继承的局限性

  • 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

  • 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

 练习

创建两个分线程,让其中一个线程输出1-100之间的偶数,另一个线程输出1-100之间的奇数。

 

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

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

相关文章

使用神经网络-遗传算法优化神经网络-风电预测故障(BP,GABP,matlab)

本项目是故障预测&#xff0c;不是时序预测&#xff0c;本质还是分类问题 1 数据集介绍 特征文件&#xff1a; 标签文件&#xff1a;共计4个标签&#xff0c;其中大多数都是正常的&#xff0c;其他是3个不正常的类别 2 使用BP网络 2.1 读取数据&#xff0c;然后选择几个…

【深度学习】图像自然语言描述生成

案例 6&#xff1a;图像自然语言描述生成&#xff08;让计算机“看图说话”&#xff09; 相关知识点&#xff1a;RNN、Attention 机制、图像和文本数据的处理 1 任务目标 1.1 任务和数据简介 ​ 本次案例将使用深度学习技术来完成图像自然语言描述生成任务&#xff0c;输入…

ubuntu强密码支持

接到新需求&#xff0c;欧盟需要ubuntu使用强密码&#xff0c;网络上找到一个包可以增加ubuntu密码增强机制&#xff0c;以下是调试过程。 sudo apt-get install libpam-pwquality 然后&#xff0c;编辑位于/etc/pam.d/目录中的common-password文件&#xff1a; sudo vim /et…

STM32F103C8T6最小系统板是一种基于STM32F103C8T6微控制器的开发板,具有丰富的外设和强大的处理能力,适用于各种嵌入式应用开发

STM32F103C8T6最小系统板是一种基于STM32F103C8T6微控制器的开发板&#xff0c;具有丰富的外设和强大的处理能力&#xff0c;适用于各种嵌入式应用开发。该开发板集成了STM32F103C8T6微控制器的核心部分、时钟电路、复位电路、USB电源管理电路等&#xff0c;非常适合初学者进行…

MySQL复制拓扑2

文章目录 主要内容一.配置基本复制结构1.分别在三台主机上停止mysqld服务&#xff0c;并对状态进行确认&#xff1a;代码如下&#xff08;示例&#xff09;: 2.对三个MySQL服务器的配置文件分别进行编辑&#xff0c;在[mysqld] 选项组中添加以下红色条目&#xff1a;3.在数据目…

深入理解Java异常处理机制(day20)

异常处理 异常处理是程序运行过程产生的异常情况进行恰当的处理技术 在计算机编程里面&#xff0c;异常的情况比所我们所想的异常情况还要多。 Java里面有两种异常处理方式&#xff1b; 1.利用trycatchfinaly语句处理异常&#xff0c;优点是分开了处理异常代码和程序正常代码…

深入浅出 -- 系统架构之负载均衡Nginx反向代理

一、Nginx反向代理-负载均衡 首先通过SpringBootFreemarker快速搭建一个WEB项目&#xff1a;springboot-web-nginx&#xff0c;然后在该项目中&#xff0c;创建一个IndexNginxController.java文件&#xff0c;逻辑如下&#xff1a; Controller public class IndexNginxControl…

【放假第3天】幻兽帕鲁 雾锁王国 我的世界 游戏云服务器选购指南 附最新价格对比表 新手、小白秒懂

更新日期&#xff1a;4月6日&#xff08;半年档 价格回调&#xff0c;京东云采购季持续进行&#xff09; 本文纯原创&#xff0c;侵权必究 【云服务器推荐】价格对比&#xff01;阿里云 京东云 腾讯云 选购指南视频截图 《最新对比表》已更新在文章头部—腾讯云文档&#xf…

前端三剑客 —— CSS (第四节)

目录 内容回顾&#xff1a; 1.常见样式 2.特殊样式 特殊样式 过滤效果 动画效果 动画案例&#xff1a; 渐变效果 其他效果&#xff1a; 多列效果 字体图标&#xff08;icon&#xff09; 内容回顾&#xff1a; 1.常见样式 text-shadow x轴 y轴 阴影的模糊程度 阴影的…

【话题:工作生活】2022年工作总结--疫情下的上海,疫情中的我。

现在是阳历2023年11月27日星期一&#xff0c;我再次开始撰写自己的年终工作总结。希望再过1、2个月&#xff0c;这份年终总结能够出炉&#xff0c;与大家相遇。 给自己定个小目标&#xff0c;年终的工作生活总结坚持写10年。我2017年毕业&#xff0c;之后就开始写每年的年终总结…

软考117-上午题-【计算机网络】-杂题+小结

一、杂题 真题1&#xff1a; 真题2&#xff1a; 真题3&#xff1a; 真题4&#xff1a; 真题5&#xff1a; 真题6&#xff1a; 真题7&#xff1a; 真题8&#xff1a; 真题9&#xff1a; 真题10&#xff1a; 真题11&#xff1a; 真题12&#xff1a; 真题13&#xff1a; 真题14&a…

c# wpf LiveCharts MVVM绑定 简单试验

1.概要 c# wpf LiveCharts MVVM绑定 简单试验 2.代码 <Window x:Class"WpfApp3.Window3"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://s…

Vue 组件的 mixin 函数,用于屏幕适配

// 屏幕适配 mixin 函数// * 默认缩放值 const scale {width: 1,height: 1, }// * 设计稿尺寸&#xff08;px&#xff09; const baseWidth 1920 const baseHeight 1080// * 需保持的比例&#xff08;默认1.77778&#xff09; const baseProportion parseFloat((baseWidth …

Java 开发工具包_JDK 各个版本 下载

Java 开发工具包_JDK 各个版本 下载&#xff1a; jdk.java.net http://jdk.java.net/ Oracle 官网&#xff1a; https://www.oracle.com/java/technologies/javase-downloads.html JDK-7 下载&#xff1a; http://jdk.java.net/java-se-ri/7 JDK-8 下载&#xff1a; https:/…

Unity性能优化篇(十四) 其他优化细节以及UPR优化分析器

代码优化&#xff1a; 1. 使用AssetBundle作为资源加载方案。 而且经常一起使用的资源可以打在同一个AssetBundle包中。尽量避免同一个资源被打包进多个AB包中。压缩方式尽量使用LZ4&#xff0c;少用或不要用LZMA的压缩方式。如果确定后续开发不会升级Unity版本&#xff0c;则可…

MySql并发事务问题

事务 事务概念&#xff1a; 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务的特性&#xff1a;ACID&#xff1a; 小…

鸿蒙实战开发-如何使用Stage模型卡片

介绍 本示例展示了Stage模型卡片提供方的创建与使用。 用到了卡片扩展模块接口&#xff0c;ohos.app.form.FormExtensionAbility 。 卡片信息和状态等相关类型和枚举接口&#xff0c;ohos.app.form.formInfo 。 卡片提供方相关接口的能力接口&#xff0c;ohos.app.form.for…

开源流程图表库(04):mxGraph,都是可视化编辑,导出使用。

mxGraph是一个用于创建和展示图形的JavaScript库。它提供了丰富的功能和工具&#xff0c;可以用于构建各种类型的图形应用程序&#xff0c;包括流程图、组织结构图、网络拓扑图等。 mxGraph的编辑器 一、mxGraph的特点和功能 以下是一些mxGraph的特点和功能&#xff1a; 强大…

FPGA的串口的收发程序设计

module uart_tx(input clk,input rst,input start,input [7:0] data,output reg tx_done,output reg tx_out );// 定义状态机的状态typedef enum logic [2:0] {IDLE, START, DATA, STOP} state_t;reg [10:0] count; // 用于计数发送的位数reg [2:0] state; // 用于记录…

耐腐蚀耐高温实验室塑料烧杯进口高纯PFA材质反应器特氟龙烧杯

PFA烧杯在实验过程中可作为储酸容器或涉及强酸强碱类实验的反应容器&#xff0c;用于盛放样品、试剂&#xff0c;可搭配电热板加热、蒸煮、赶酸用。 外壁均有凸起刻度&#xff0c;直筒设计&#xff0c;带翻边&#xff0c;便于夹持和移动&#xff0c;边沿有嘴&#xff0c;便于倾…