【Java多线程】初识线程及三种创建方式

news2025/1/22 13:06:53

➤ Java多线程编程【一文全解】

文章目录

  • 线程简介
  • 进程的创建
    • > 继承 Thread 类
    • > 实现 Runnable 接口
    • > 实现 Callable 接口

线程简介

在这里插入图片描述
        普通的程序中,方法的调用是执行到方法的时候,程序跳转到方法体中进行,是按照顺序进行的,而多线程则是多任务“同时”进行,即“边吃饭边看电视”,而不是“吃完饭再看电视”,多线程是并发执行的。(并发:短时刻内交替执行,宏观上是“同时”执行的)

  • 程序是指令和数据的有序集合,是静态的存储;
  • 进程是执行程序的一次执行过程,是动态的执行,是系统资源分配的单位;
  • 一个进程可包含若干个线程,一个进程至少拥有一个线程,线程是CPU调度和执行的单位;

可以这么理解:电脑上的QQ存储在硬盘中,是一个程序,当我们运行它的时候,它就成为了一个进程,得到了系统资源分配,而它的功能比如可以同时聊天同时打电话还可以逛空间和发邮件,这些诸多功能就是线程

注意:很多多线程其实是模拟出来的,真正的多线程是指有多个CPU,即多核,如服务器。如果是模拟出来的多线程,即在一个CPU的情况下,在同一个时间点,CPU只能执行一个代码,但因为切换的很快,就有“同时”执行的错觉,这就是并发。

  • 线程是独立的执行路径;
  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程(垃圾回收);
  • 主线程即 main()函数,是系统的入口,用于执行整个程序;
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序由调度器(操作系统)就决定,无法干预;
  • 对同一份资源操作时,会存在资源抢夺问题,需要加入并发控制;
  • 线程会带来额外的开销,如CPU调度时间,并发控制开销;
  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致;
  • 线程可以共享进程的资源,不必再单独分配,所以线程的引入提升了性能。

Java虚拟机允许应用程序同时执行多个执行线程,每个线程都有优先权


进程的创建

进程的创建有如下三种方式:
在这里插入图片描述

> 继承 Thread 类

  • 自定义线程类继承 Thread 类

  • 重写 run( ) 方法,编写程序执行体;

  • 创建线程对象,调用 start( ) 方法启动线程;

通过打印输出来判断多线程的执行顺序:

//创建线程方式一:继承Thread类,重写run()方法,调用start()方法
public class TestThread01 extends Thread{
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 10; i++) {
            System.out.println("敲代码+"+i);
        }
    }
    
    public static void main(String[] args) {
        //main主线程
        
        //创建一个线程对象
        TestThread01 t1 = new TestThread01();
        
        //调用start()方法开启
        t1.start();
        
        for (int i = 0; i < 1000; i++) {
            System.out.println("学习Java+"+i);
        }
    }
}

运行可知,并没有按顺序执行,而是并发执行的(由CPU调度执行):
在这里插入图片描述

> 实现 Runnable 接口

  • 定义 MyRunnable 类实现 Runnable 接口
  • 实现 run( ) 方法,编写线程执行体;
  • 创建线程对象,调用 start( ) 方法启动线程;

推荐使用 Runnable对象,因为Java单继承的局限性

//创建线程方式二:实现Runnable接口,重写run()方法,执行线程需要丢入Runnable接口实现类,调用start方法
public class TestThread02 implements Runnable{
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 10; i++) {
            System.out.println("敲代码+"+i);
        }
    }
    public static void main(String[] args) {
        //创建一个Runnable接口的实现类对象
        TestThread02 testThread02 = new TestThread02();
        /*
        创建线程对象,通过线程对象来开启线程
        Thread thread = new Thread(testThread02);
        thread.start();
         */
        new Thread(testThread02).start();
        
        for (int i = 0; i < 1000; i++) {
            System.out.println("学习Java+"+i);
        }
    }

}

在这里插入图片描述

对比 继承Thread类实现Runnable接口 两种方法:在这里插入图片描述


继承Thread类

  • 子列继承Thread类具备多线程能力;
  • 启动线程:子类对象.start( );
  • 不建议使用:避免OOP单继承局限性;

实现Runnable接口

  • 实现Runnable具有多线程能力;
  • 启动线程:传入目标对象+Thread对象.start( );
  • 推荐使用:避免单继承局限性,方便同一个对象被多个线程使用;

> 实现 Callable 接口

  1. 实现Callable接口,需要返回值类型;
  2. 重写call方法,需要抛出异常;
  3. 创建目标对象;
  4. 创建执行服务:
    ExecutorService ser = Executors.newFixedThreadPool(1);
  5. 提交执行:Future result = ser.submit(thread01);
  6. 获取结果:boolean r1 = result.get();
  7. 关闭服务:ser.shutdownNow();
//进程创建方式三:实现Callable接口
public class TestCallable implements Callable<Boolean> {
    //重写call()方法
    @Override
    public Boolean call() throws Exception {
        System.out.println("方法体");
        return true;
    }

    public static void main(String[] args) throws Exception {
    	//创建对象
        TestCallable tc = new TestCallable();

        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(1);

        //提交执行
        Future<Boolean> result = ser.submit(tc);//通过服务提交线程

        //获取结果
        boolean b = result.get(); //call()方法返回类型
        
        //关闭服务
        ser.shutdown();
    }
}

Callable的好处:

  1. 可以定义返回值;
  2. 可以抛出异常;

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

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

相关文章

说说未来趋势 「元宇宙」是什么?

最近「元宇宙」概念大火&#xff0c;连星爷等各行各业的各路大佬都可以传出消息布局进入这一个领域&#xff0c;那么这是不是意味这IT信息化时代的下一个风口&#xff0c;就是元宇宙呢&#xff1f;按小郭说呀&#xff0c;这目前来看&#xff0c;这个趋势是必然的&#xff0c;就…

Spirng 痛苦源码学习(一)——总起spring(一)

文章目录前言一、总览Spring的bean1&#xff09;bean的过程【先了解具体的生命周期后面弄】2&#xff09;hello spring 简单bean操作二、总览AOP- 1、test coding- 2、- debug- 3、- 总结debug三、总览事务- 1、- test coding- 2、 debugging- 3、 事务失效- 4、事务总结前言 …

cpu设计和实现(流水线暂停)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;数字电路里面流水线的引入&#xff0c;主要是为了提高数据的处理效率。那么&#xff0c;鉴于此&#xff0c;为什么又要对…

ssm宠物商城管理系统源码

在 Internet飞速开展的今天&#xff0c;互联网成为人们快速获取、发布和传 递信息的重要渠道&#xff0c;它在人们学习、工作、生活等各个方面发挥着重要的作用。 因此建立在 Internet应用上的地位显而易见&#xff0c;它已成为政府、企事业单位信息化 建立中的重要组成局部&am…

[附源码]SSM计算机毕业设计网上书店管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【kafka】十五、kafka消费者API

kafka消费者API Consumer消费数据时的可靠性是很容易保证的&#xff0c;因为数据在kafka中是持久化的&#xff0c;故不用担心数据丢失的问题。 由于consumer在消费过程中可能会出现断电宕机的等故障&#xff0c;consumer恢复后&#xff0c;需要从故障前的位置继续消费&#xf…

visual studio 2019 + Qt 开发,使用visual leak detector检测内存泄漏

选择了在vs2019上开发Qt, 遇到了内存泄露问题。还好vs上有方便的visual leak detector&#xff08;vld&#xff09;检测工具。 虽然官网上只支持到vs2015, 但vs2019上也能用。 具体参考这位博主的文章&#xff1a;https://blog.csdn.net/qq_22108657/article/details/1208843…

Redis数据库安装(Windows)

目录 一、下载Windows安装包 二、启动Redis 1.在终端中启动 2.使用start.bat文件启动 3.添加服务启动 三、安装Redis可视化管理工具 1.安装Redis图形客户端 2.连接数据库 一、下载Windows安装包 下载地址&#xff1a;Releases tporadowski/redis GitHub 选择下载相…

单链表的递归详解 (leetcode习题+ C++实现)

文章目录合并两个有序链表翻转链表链表中移除节点合并两个有序链表 传送门&#xff1a; https://leetcode.cn/problems/merge-two-sorted-lists/description/ 题目要求&#xff1b; 给你两个有序的链表&#xff0c;将这两个链表按照从小到大的关系&#xff0c;合并两个链表为…

Mybatis快速入门

Mybatis安装与配置 Mybatis概述 Mybatis本质上是一个别人写好的框架&#xff0c;用于简化 JDBC 开发&#xff0c;通过Mybatis框架&#xff0c;可以极大的降低JDBC的开发难度。 官方文档&#xff1a;https://mybatis.org/mybatis-3/zh/index.html Mybatis快速入门 需求&…

MySQL进阶实战10,MySQL全文索引

一、全文索引 全文索引的目的是 通过关键字的匹配进行查询过滤&#xff0c;基于相似度的查询&#xff0c;而不是精确查询。 全文索引利用分词技术分析出文字中某关键字的频率和重要性&#xff0c;并按照一定的算法智能的筛选出我们想要的结果。 全文索引一般用于字符串中某关…

tomcat服务器安装及配置教程(保姆级教程)

Tomcat安装教程 &#xff08;以tomcat-9.0.62为例&#xff1a;&#xff09; 1.下载安装包 可以从官网下载安装包&#xff1a; &#xff08;1&#xff09;从官网下载 输入网址进入官网 选择版本10&#xff0c;版本9&#xff0c;或者版本8&#xff0c;都可以&#xff0c;这里…

掘金热榜首推!阿里内部都在用的Java后端面试笔记,囊括99%的主流技术

纵观今年的技术招聘市场&#xff0c; Java依旧是当仁不让的霸主 &#xff01;即便遭受 Go等新兴语言不断冲击&#xff0c;依旧岿然不动。究其原因&#xff1a; Java有着极其成熟的生态&#xff0c;这个不用我多说&#xff1b;Java在 运维、可观测性、可监 控性方面都有着非常优…

Spring Boot JPA 本机查询示例

在本教程中&#xff0c;您将了解如何在 Spring 引导中使用 Spring Data JPA 本机查询示例&#xff08;带参数&#xff09;。我将向您展示&#xff1a; 将 Spring JPA 本机查询与Query注释一起使用的方法如何在 Spring 引导中执行 SQL 查询具有 WHERE 条件的 JPA 选择查询示例 …

动态SQL

动态SQL 可以根据具体的参数条件&#xff0c;来对SQL语句进行动态拼接。比如在以前的开发中&#xff0c;由于不确定查询参数是否存在&#xff0c;许多人会使用类似于where 1 1 来作为前缀&#xff0c;然后后面用AND 拼接要查询的参数&#xff0c;这样&#xff0c;就算要查询的…

MongoShake数据灾备与迁移

安装部署 解压 建议部署在离目标端近的地方&#xff0c;比如部署再目标端本地 tar -zxvf mongo-shake-v2.8.1.tgz配置 同构环境下主要参数 启动 执行下述命令启动同步任务&#xff0c;并打印日志信息&#xff0c;-verbose 0表示将日志打印到文件&#xff0c;在后台运行 …

【Linux从入门到放弃】Linux基本指令大全

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《Linux从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; L…

黑苹果之微星(MSI)主板BIOS详细设置篇

很多童鞋安装黑苹果的时候会卡住&#xff0c;大部分原因是cfg lock 没有关闭&#xff0c;以及USB端口或SATA模式设置错误。 为了避免这些安装阶段报错的情况发生&#xff0c;今天给大家分享一下超详细的BIOS防踩坑设置指南--微星&#xff08;MSI&#xff09;主板BIOS篇&#xf…

springcloud总结篇

一.整体结构 springcloud总体架构 对比学习 二.具体 1.场景模拟 订单服务调用库存服务来更新数据库中的库存 2.springcloud问题解析 Eureka OpenFeign &#xff08;RibbonRestTemplate&#xff09; Hystrix Gateway config Bus 订单服务只知道库存服务的名称…

Python测试-unittest,2022-11-27

(2022.11.27 Sun) unittest是Python自带的单元测试框架。unittesthtml和pytestallure(测试报告)成为常用的自动测试和报告的框架组合。 unittest-archi-2022-11-23-2114.png 概念 test case测试用例&#xff1a;测试用例是测试的基本单元&#xff0c;用于测试一组特定输入的特…