Java-多线程入门

news2024/11/13 10:43:35

        多线程是指在软件或硬件上实现多个线程并发执行的技术。为了更好地理解多线程,首先需要了解几个基本概念:

了解概念

1.程序

        程序是为完成特定任务、用某种语言编写的一组指令的集合。它是一个静态的概念,通常存储在磁盘或其他非易失性存储器中,说白了就是我们写的代码。

2.进程

        进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有独立的内存空间和系统资源。

3.线程

        线程是进程中的一个执行单元,是CPU调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的资源,但每个线程有自己的栈和寄存器状态。

4.并发

        并发是指多个任务在同一时间段内交替执行,但由于CPU切换任务的速度非常快,给人的感觉像是同时执行。

5.并行

        并行是指多个任务在同一时刻真正的同时执行,这通常需要多核处理器或其他并行处理硬件的支持。

6.cpu核

CPU核是处理器的计算单元,一个多核处理器可以在同一时刻执行多个线程,从而实现并行处理。

基本使用方法

        多线程编程是提高程序并发处理能力的重要手段。下面通过具体的代码示例来展示如何使用多线程

1. 通过继承Thread类

// 通过继承Thread类来创建线程
class MyThread extends Thread {
    // 重写run方法,线程启动后将执行run方法中的代码
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " 执行 " + i);
            try {
                // 线程休眠100毫秒
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) {
        // 创建两个线程对象
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        
        // 启动线程
        thread1.start();
        thread2.start();
    }
}
  • MyThread类继承了Thread类,并重写了run方法。
  • main方法中创建了两个MyThread对象,并调用start方法启动线程。

2. 实现Runnable接口

// 通过实现Runnable接口来创建线程
class MyRunnable implements Runnable {
    // 实现run方法,线程启动后将执行run方法中的代码
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " 执行 " + i);
            try {
                // 线程休眠100毫秒
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class RunnableDemo {
    public static void main(String[] args) {
        // 创建Runnable对象
        MyRunnable myRunnable = new MyRunnable();
        
        // 创建两个线程对象,并将Runnable对象作为参数传递给Thread构造函数
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);
        
        // 启动线程
        thread1.start();
        thread2.start();
    }
}

 

  • MyRunnable类实现了Runnable接口,并实现了run方法。
  • main方法中创建了一个MyRunnable对象,并将其作为参数传递给两个Thread对象,然后调用start方法启动线程。

3. 通过Callable和Future创建线程

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

// 通过实现Callable接口来创建线程
class MyCallable implements Callable<Integer> {
    // 实现call方法,线程启动后将执行call方法中的代码,并返回一个结果
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 5; i++) {
            sum += i;
            System.out.println(Thread.currentThread().getName() + " 执行 " + i);
            try {
                // 线程休眠100毫秒
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return sum;
    }
}

public class CallableDemo {
    public static void main(String[] args) {
        // 创建Callable对象
        MyCallable myCallable = new MyCallable();
        
        // 创建FutureTask对象,并将Callable对象作为参数传递给FutureTask构造函数
        FutureTask<Integer> futureTask1 = new FutureTask<>(myCallable);
        FutureTask<Integer> futureTask2 = new FutureTask<>(myCallable);
        
        // 创建线程对象,并将FutureTask对象作为参数传递给Thread构造函数
        Thread thread1 = new Thread(futureTask1);
        Thread thread2 = new Thread(futureTask2);
        
        // 启动线程
        thread1.start();
        thread2.start();
        
        try {
            // 获取线程执行结果
            System.out.println("Thread 1 结果: " + futureTask1.get());
            System.out.println("Thread 2 结果: " + futureTask2.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}
  • MyCallable类实现了Callable接口,并实现了call方法,该方法返回一个整数结果。
  • main方法中创建了一个MyCallable对象,并将其作为参数传递给两个FutureTask对象。
  • FutureTask对象作为参数传递给两个Thread对象,并调用start方法启动线程。
  • 使用FutureTaskget方法获取线程的执行结果。

总结

     可以看到,Thread实现了Runnable接口 ,他是一个类,我们可以直接继承Thread类来实现线程,也可以通过直接实现Runnable接口来使用,感兴趣的可以自己去看一下源码,然而Threa本身并没有Run方法,Run方法是接口里面的。

         多线程的底层实现机制原理涉及到线程调度、同步和互斥等概念。操作系统通过线程调度器来决定哪个线程在何时执行。为了确保多个线程能够正确地共享资源,需要使用同步机制,如锁(synchronized关键字)和条件变量(如Java中的wait和notify方法)。  多线程想要理解透彻需要花费一定的时间,也有难度,底层原理我会后面再写,今天这篇文章只需要简单了解入门即可。

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

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

相关文章

vxe-table 更新到最新版本

当前版本&#xff1a; "vxe-table": "^4.3.0-beta.3" 更新后&#xff1a; "vxe-table": "^4.7.75" 需要调整代码&#xff1a; 更改前main.js 更改后&#xff1a;

Jenkins Environment Injector Plugin 插件详解

引言 在做自动化测试的过程中&#xff0c;我们需要经常发送测试报告给相关研发、产品和上级&#xff0c;但是Jenkins邮件模板不支持Javascritpt脚本来动态生成数据&#xff0c;只支持静态的HTML代码&#xff0c;那么我们就没有办法了吗&#xff1f;非也&#xff0c;我们可以通…

SQL进阶技巧:经典问题题-换座位

目录 0 问题描述 1 数据准备 2 问题分析 3 小结 0 问题描述 表 seat中有2个字段id和student id 是该表的主键(唯一值)列,student表示学生姓名。 该表的每一行都表示学生的姓名和 ID。 id 是一个连续的增量。 编写解决方案来交换每两个连续的学生的座位号。如果学生的数量…

Windows下Nacos安装与配置

目录 1. 下载Nacos 2. 解压安装包 3. 配置系统环境变量 4. 启动Nacos 5. 配置数据库为mysql 6. 配置鉴权默认值 1. 下载Nacos 我下载的版本是2.3.0。 下载地址&#xff1a;Nacos Server 下载 | Nacos 官网 但是我从官方那里下载超级慢&#xff0c;找了一个链接下载&#…

Milvus 向量数据库进阶系列丨构建 RAG 多租户/多用户系统 (下)

本系列文章介绍 在和社区小伙伴们交流的过程中&#xff0c;我们发现大家最关心的问题从来不是某个具体的功能如何使用&#xff0c;而是面对一个具体的实战场景时&#xff0c;如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中&a…

Python将两个Excel文件按相同字段合并到一起

在工作中我们需要将两个有关联的数据文件合并成一个Excel 1. 创建两个excel文件 test1 test2 2. 使用Pandas 数据分析工具进行合并 Pandas 一个强大的分析结构化数据的工具集&#xff0c;提供了易于使用的数据结构和数据分析工具&#xff0c;特别适用于处理结构化数据&#x…

Linux操作系统软件管理

一.软件安装包类型 1.常见软件安装包格式 源码软件 .tar.gz&#xff0c;.tar.bz2 优点&#xff1a;从功能使用的角度来讲&#xff0c;比rpm软件安装包更加灵活&#xff0c; 比如 在使用源码软件安装包的时候&#xff0c;可以自行选择安装软件的目录&#xff0c;这样操作便…

TypeScript与vue

一、为组件的props标注类型 - 在没有使用TS之前&#xff0c;是这样接受props&#xff1a; - 在TS环境中&#xff0c;是这样接受props&#xff1a; - 对于props的可选项如何限制呢&#xff1f; 1、类型限制 类型限制在接收的时候就已经定义好了 2、可选属性&#xff08;必填限制…

华媒舍:8个为什么要选择国外纳斯达克大屏推广的原因

1.纳斯达克大屏的知名度和美誉度纳斯达克大屏是全球有名气的金融业信息表明平台之一&#xff0c;它在全球金融体系有着广泛的知名度和美誉度。以在纳斯达克大屏中进行推广&#xff0c;能够让更多人关注与掌握推广具体内容&#xff0c;从而增加品牌曝光率。 2.纳斯达克大屏高客流…

代码随想录Day 31|leetcode题目:56.合并区间、738.单调递增的数字、968.监控二叉树

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 贪心算法Part05题目题目一&#xff1a;56. 合并区间解题思路 题目二&#xff1a;738.单调递增的数字解题思路&#xff1a;暴力解法&#xff1a;结果超时贪心算法 题目三&#xff1a; 968.监控二叉…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 9月1日,星期日

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年9月1日 星期日 农历七月廿九 1、 未来一周&#xff0c;四川东部、重庆等地持续高温天气&#xff0c;最高气温可达40&#xff5e;42℃。 2、 山西明确&#xff1a;今日起&#xff0c;职工医保个人账户家庭共济范围由直系亲…

QNN:基于QNN+example重构之后的yolov8det部署

QNN是高通发布的神经网络推理引擎&#xff0c;是SNPE的升级版&#xff0c;其主要功能是&#xff1a; 完成从Pytorch/TensorFlow/Keras/Onnx等神经网络框架到高通计算平台的模型转换&#xff1b; 完成模型的低比特量化&#xff08;int8&#xff09;&#xff0c;使其能够运行在高…

干货分享|分享一款实用的网盘图标删除器 Drive Icon Manager v2.2

问题&#xff1a;在Windows平台“此电脑”及“资源管理器侧边栏”中会出现各种第三方图标&#xff0c;如百度网盘、WPS网盘、迅雷下载。 Drive Icon Manager 下载方法 1.打开下面网址--选择最新版本进行下载GitHub - Return-Log/Drive-Icon-Manager: 可以轻松删除‘此电脑’及‘…

基于SSM+小程序的宿舍管理系统(宿舍1)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 本宿舍管理系统小程序有管理员和学生两个角色。 1、管理员功能有个人中心&#xff0c;公告信息管理&#xff0c;班级管理&#xff0c;学生管理&#xff0c;宿舍信息管理&#xff0c;宿舍…

算法——支持向量机(support vector machines,SVM)

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正 支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种监督学习算法&#xff0c;广泛用于分类任务&#xff0c;也可以用于回归和异常检测等问题。SVM的核心思想是通过在特征空间中找…

单片机内存区域划分

目录 一、C 语言内存分区1、栈区2、堆区3、全局区&#xff08;静态区&#xff09;4、常量区5、代码区6、总结 二、单片机存储分配1、存储器1.1 RAM1.2 ROM1.3 Flash Memory1.4 不同数据的存放位置 2、程序占用内存大小 一、C 语言内存分区 C 语言在内存中一共分为如下几个区域…

高效达人必备!Simple Sticky Notes让灵感与任务不再遗漏!

前言 阿尔伯特爱因斯坦所言&#xff1a;“我们不能用制造问题时的同一水平思维来解决它。”这句话深刻地揭示了创新与突破的必要性。正是基于这样的理念&#xff0c;Simple Sticky Notes这款桌面便签软件以其独特的创新视角和实用性&#xff0c;在众多同类软件中脱颖而出。 它…

【原型设计工具评测】Axure、Figma、Sketch三强争霸

在当今的数字化设计领域&#xff0c;选择合适的原型设计工具对于项目的成功至关重要。Axure、Figma 和 Sketch 是目前市场上最受欢迎的三款原型设计工具&#xff0c;它们各具特色&#xff0c;满足了不同用户的需求。本文将对这三款工具进行详细的对比评测&#xff0c;帮助设计师…

Fine-Grained Egocentric Hand-Object(中文翻译)

精细化自我中心手-物体分割&#xff1a; 数据集、模型&#xff08;model&#xff09;与应用 灵芝张1, 盛昊周1, 西蒙斯滕特 $ {}^{2} $, 和健博石 $ {}^{1} $ 摘要。 自我中心视频提供了高保真度建模人类行为的细粒度信息。手和交互对象是理解观众行为和意图的一个关键方面。…

Pandas 10-绘制饼图

1. 准备数据 首先&#xff0c;需要准备一个DataFrame。 import pandas as pd# 创建一个DataFrame data {Category: [A, B, C, D],Value: [15, 30, 45, 10] }df pd.DataFrame(data) print(df)输出&#xff1a; Category Value 0 A 15 1 B 30 2 …