Java基础——多线程创建

news2024/12/23 11:51:30

(1)什么是线程?

  • 线程(thread)是一个程序内部的一条执行路径。
  • 程序中只有一条执行路径,那么这个程序就是单线程的程序。

 (2)多线程是什么?

  • 多线程是指从软硬件上实现多执行流程的技术。

(3)多线程的创建

3.1.继承Thread类

  • 继承Thread类(定义一个子类继承线程类java.lang.Thread)
  • 重写run方法
  • 创建线程对象
  • 调用start()方法启动

注意:

1.为什么不直接调用run方法,而是调用start启动线程

  • 直接调用run方法会当成普通方法执行,此时相当于还是单线程执行。
  • 只有调用start方法才是启动一个新的线程执行。 

2.不要把主线程放在子线程之前,因为主线程先跑,相当于一个单线程的效果。

3.虽然代码简单,但是存在单继承的局限性,线程类继承Thread后,不能继承其他类,不便于扩展。

/**
   目标:多线程的创建方式一:继承Thread类实现。
 */
public class ThreadDemo1 {
    public static void main(String[] args) {
        // 3、new一个新线程对象
        Thread t = new MyThread();
        // 4、调用start方法启动线程(执行的还是run方法)
        t.start();

        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行输出:" + i);
        }

    }
}

/**
   1、定义一个线程类继承Thread类
 */
class MyThread extends Thread{
    /**
       2、重写run方法,里面是定义线程以后要干啥
     */
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行输出:" + i);
        }
    }
}

3.2.实现Runnable接口

  • 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法。
  • 创建MyRunnable任务类。
  • 把MyRunnable任务对象交给Thread处理。
  • 调用线程对象的start()方法启动线程。
  • Thread的构造器:

优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。

缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。

/**
   目标:学会线程的创建方式二,理解它的优缺点。
 */
public class ThreadDemo2 {
    public static void main(String[] args) {
        // 3、创建一个任务对象
        Runnable target = new MyRunnable();
        // 4、把任务对象交给Thread处理
        Thread t = new Thread(target);
        // Thread t = new Thread(target, "1号");
        // 5、启动线程
        t.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("主线程执行输出:" + i);
        }
    }
}

/**
   1、定义一个线程任务类 实现Runnable接口
 */
class MyRunnable  implements Runnable {
    /**
       2、重写run方法,定义线程的执行任务的
     */
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("子线程执行输出:" + i);
        }
    }
}

 (匿名内部类形式)

  • 可以创建Runnable的匿名内部类对象。
  • 交给Thread处理。
  • 调用线程对象的start()启动线程。
/**
   目标:学会线程的创建方式二(匿名内部类方式实现,语法形式)
 */
public class ThreadDemo2Other {
    public static void main(String[] args) {
        Runnable target = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("子线程1执行输出:" + i);
                }
            }
        };
        Thread t = new Thread(target);
        t.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("子线程2执行输出:" + i);
                }
            }
        }).start();

        new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    System.out.println("子线程3执行输出:" + i);
            }
        }).start();

        for (int i = 0; i < 10; i++) {
            System.out.println("主线程执行输出:" + i);
        }
    }
}

3.3.利用Callable,FutureTask接口实现

1.得到任务对象

  • 定义类实现Callable接口,重写call方法,封装要做的事情。
  • 用FutureTask把Callable对象封装成线程任务对象。

2.把线程任务对象交给Thread处理。

3.调用Thread的start方法启动线程,执行任务。

4.线程执行完毕后,通过FutureTask的get方法去获取任务执行结果。

 

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
   目标:学会线程的创建方式三:实现Callable接口,结合FutureTask完成。
 */
public class ThreadDemo3 {
    public static void main(String[] args) {
        // 3、创建Callable任务对象
        Callable<String> call = new MyCallable(100);
        // 4、把Callable任务对象 交给 FutureTask 对象
        //  FutureTask对象的作用1: 是Runnable的对象(实现了Runnable接口),可以交给Thread了
        //  FutureTask对象的作用2: 可以在线程执行完毕之后通过调用其get方法得到线程执行完成的结果
        FutureTask<String> f1 = new FutureTask<>(call);
        // 5、交给线程处理
        Thread t1 = new Thread(f1);
        // 6、启动线程
        t1.start();


        Callable<String> call2 = new MyCallable(200);
        FutureTask<String> f2 = new FutureTask<>(call2);
        Thread t2 = new Thread(f2);
        t2.start();

        try {
            // 如果f1任务没有执行完毕,这里的代码会等待,直到线程1跑完才提取结果。
            String rs1 = f1.get();
            System.out.println("第一个结果:" + rs1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            // 如果f2任务没有执行完毕,这里的代码会等待,直到线程2跑完才提取结果。
            String rs2 = f2.get();
            System.out.println("第二个结果:" + rs2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
    1、定义一个任务类 实现Callable接口  应该申明线程任务执行完毕后的结果的数据类型
 */
class MyCallable implements Callable<String>{
    private int n;
    public MyCallable(int n) {
        this.n = n;
    }

    /**
       2、重写call方法(任务方法)
     */
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= n ; i++) {
            sum += i;
        }
        return "子线程执行的结果是:" + sum;
    }
}

3.4.三种方式的比较:

 

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

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

相关文章

Python入门教程+项目实战-10.5节: 程序实战-冒泡排序算法

目录 10.5.1 排序算法简介 10.5.2 冒泡排序算法 10.5.3 系统学习python 10.5.1 排序算法简介 所谓排序&#xff0c;是指将数据集合中的元素按从小到大的顺序进行排列&#xff0c;或按从大到小的顺序进行排列。前者称为升序排序&#xff0c;后者称为降序排序。在数据结构与算…

jenkins自动化部署配置

文章目录 1. jenkins 插件安装2. 配置2.1 全局工具配置2.2 全局配置2.2.1 gitee 配置 3. 创建任务添加gitee ssh jenkins 开机自启动 1. jenkins 插件安装 ant Build Failure AnalyzerBuild Monitor ViewBuild Timeout dockerEmail Extension Plugin giteegithubgradle javama…

【11 EL表达式JSTL 学习笔记 】

EL表达式 学习笔记 1. EL表达式介绍2. EL表达式的基本使用3. EL 表达式获取数据4. EL注意事项5. EL表达式运算符关系运算符逻辑运算符empty&三元运算符 6. EL表达式细节7. EL表达式11个隐式对象8. JSTL8.1 JSTL的基本使用 1. EL表达式介绍 简化了 java代码块和jsp表达式的…

ChatGPT的开源平替,终于来了!

最近这段时间&#xff0c;一个号称全球最大ChatGPT开源平替项目Open Assistant引起了大家的注意。 这不最近还登上了GitHub的Trending热榜。 https://github.com/LAION-AI/Open-Assistant 根据官方的介绍&#xff0c;Open Assistant也是一个对话式的大型语言模型项目&#xff…

RUST 每日一省:生命周期作用域

生命周期 一个变量的生命周期就是它从创建到销毁的整个过程。 作用域 我们声明的每个变量都有作用域。作用域其实是变量和值存在的环境。作用域是由一对花括号表示的。例如&#xff0c;使用块表达式会创建一个作用域&#xff0c;即任何以花括号开头和结尾的表达式。此…

RabbitMQ-整合mqtt

用 springboot rabbitmq可以搭建物联网&#xff08;IOT&#xff09;平台&#xff0c;rabbitmq 不是消息队列吗&#xff0c;原来rabbitmq有两种协议&#xff0c;消息队列是用的AMQP协议&#xff0c;而用在智能硬件中的是MQTT协议。 一、rabbitmq是什么&#xff1f; RabbitMQ就…

一张图了解GPU、CUDA、CUDA toolkit和pytorch的关系

文章目录 GPU、Cuda Driver和 Cuda Toolkit的图解关系省流&#xff0c;简略版本要实现多版本的cuda怎么办 复杂版&#xff08;你要是觉得简略版说的太简单&#xff0c;这里给你找文档证明&#xff09;一、Nvidia Driver和CUDA Toolkit的关系安装GPU显卡驱动Nvidia Driver 二、C…

uniapp请求图片时候发现提示GET http://localhost:xxxx/undefined 401,undefined:1解决办法【伸手党福利】

同理解决问题&#xff1a;所有请求发起完成之后执行业务逻辑 目录 现象原因解决办法方法1&#xff1a;提前给变量一个非空默认值方法2&#xff1a;使用前端图片代替后端方法3&#xff1a;使用异步加载判断&#xff1a;注意&#xff1a;这种直接在页面判断内容是否为空或者undef…

Java JVM基础入门(一):jvm的组成、串池、常量池、常用程序调优参数

JVM JVM是java的虚拟机&#xff0c;java的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收功能 JDK、JRE、JVM的关系图 常见的JVM&#xff1a; oracle的Hotspot是我们通常使…

矿山电子封条智能监管算法 yolov8

矿山电子封条智能监管系统通过YOLOv8python网络模型技术&#xff0c;矿山电子封条智能监管算法模型在对矿井人数变化、生产作业状态、出入井人员等情况实时监测分析&#xff0c;发现煤矿人员作业及状态异常动态及时告警&#xff0c;自动将报警信息推送给后台。YOLOv8 算法的核心…

k8s部署ingress-nginx步骤

目录 一、ingress简介 二、部署ingress controller、ingress-service 三、创建对外服务deployment和service 四、创建HTTP代理yaml 五、测试 六、公网域名测试 七、参考博客 一、ingress简介 service的作用体现在两个方面&#xff0c;对集群内部&#xff0c;它不断跟踪…

[计算机图形学]光线追踪的基本原理(前瞻预习/复习回顾)

一、光栅化的弊端 我们为什么要用光线追踪呢&#xff0c;在之前的篇章中&#xff0c;我们提到了&#xff0c;光栅化的方式很难表示一些全局的效果&#xff0c;如(1)软阴影&#xff0c;(2)Glossy的反射(类似镜子但又不像镜子那么光滑的材质&#xff0c;如打磨的铜镜和一些金属)&…

【GIT】git push后github没看到pull requests解决

当你在Github上push代码后&#xff0c;如果在远程仓库中没有看到pull request请求&#xff0c;那么有以下几种可能的原因&#xff1a; 未创建pull request 如果在本地使用git push命令将修改推送到Github上&#xff0c;但还没有在Github上创建pull request请求&#xff0c;则不…

FreeRTOS 队列(一)

文章目录 一、队列简介1. 数据存储2. 多任务访问3. 出队阻塞4. 入队阻塞5. 队列操作过程图示 二、队列结构体三、队列创建1. 函数原型&#xff08;1&#xff09;函数 xQueueCreate()&#xff08;2&#xff09;函数 xQueueCreateStatic()&#xff08;3&#xff09;函数 xQueueGe…

Golang每日一练(leetDay0045)

目录 133. 克隆图 Clone Graph &#x1f31f;&#x1f31f; 134. 加油站 Gas Station &#x1f31f;&#x1f31f; 135. 分发糖果 Candy &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 …

【PR 基础】设置上下黑白边的两种方法

方法1 点击 文件-》新建-》旧版标题 点击确定 点击矩形工具 利用矩形工具框选出上下黑白边 款选完成后点击关闭 将刚创建的字幕拖入轨道 可以修改其持续时长与视频时长保持一致 如果想要修改字幕可以双击来修改 比如可以将颜色改为黑色 方法2 点击号&#xff0c;再选择安全边…

如何在表格里面使用VSTACK、HSTACK等函数

如何在表格里面使用VSTACK、HSTACK等函数 书接前文 ONLYOFFICE 桌面编辑器 v7.3 新功能介绍 里面介绍了最新版本的表格里面&#xff0c;添加的公式将帮助您更高效地进行数据计算&#xff1a;TEXTBEFORE、TEXTAFTER、TEXTSPLIT、VSTACK、HSTACK、TOROW、TOCOL、WRAPROWS、WRA…

IPSEC VPN

1.数据认证的介绍、作用、实现的技术手段 数据认证是指通过一系列验证过程检查数据的完整性、真实性、可靠性和准确性&#xff0c;以确保这些数据来自于已知或可信的来源。数据认证的目的是保护数据免受篡改、冒充或欺骗等威胁&#xff0c;确保数据的安全性和可信度。实现数据…

Windows 彻底卸载联软流氓软件(亲测可用)

文章目录 1、前言2、卸载步骤&#xff08;1&#xff09;打开服务&#xff0c;将所有Uni开头的服务都禁用&#xff0c;某些服务禁用后可能还是会自启&#xff0c;不过不影响&#xff08;2&#xff09;进入安全模式&#xff0c;电脑重启&#xff08;3&#xff09;重启后桌面显示了…

怎么将照片KB调小?压缩照片kb的几个方法

将照片KB调小的意思是将照片文件的大小缩小&#xff0c;使其占据更小的存储空间。在一些特定场景下&#xff0c;如网页设计、邮件发送、上传文件等&#xff0c;限制了文件大小&#xff0c;因此需要将照片压缩到规定大小以内。通常情况下&#xff0c;压缩后的照片质量会相应降低…