深入探讨Java多线程

news2024/11/15 17:33:07

我的主页:2的n次方_    

在这里插入图片描述

 

1. 多线程的概念

多线程是指在同一个程序中同时执行多个线程的技术。线程是操作系统能够独立调度和执行的最小单位。在Java中,线程由Thread类来表示,所有的线程都是通过这个类或其子类来创建和控制的。通过合理的多线程设计,程序可以在一个处理器上同时执行多个任务,极大地提高了程序的执行效率。

2. Java中实现多线程的方式

2.1 继承Thread类

通过继承Thread类并重写其run()方法,我们可以创建一个新的线程。run()方法包含了线程在启动后要执行的代码。

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        
        thread1.start();
        thread2.start();
    }
}

在这个例子中,我们创建了两个线程,每个线程都会执行run()方法中的代码。start()方法用于启动线程,而不是直接调用run()方法。

2.2 实现Runnable接口

相比继承Thread类,实现Runnable接口更为灵活,因为Java支持单继承但允许实现多个接口。

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

public class Main {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());
        
        thread1.start();
        thread2.start();
    }
}

在这个例子中,我们创建了两个线程,并分别传入实现了Runnable接口的对象。Thread类的构造函数接受一个Runnable对象,这使得线程的创建更加灵活。

2.3 使用Callable和Future

Runnable接口的run()方法无法返回结果,而Callable接口的call()方法则可以返回结果,并且可以抛出异常。配合Future接口,Callable可以用来处理需要返回值的任务。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 5; i++) {
            sum += i;
        }
        return sum;
    }
}

public class Main {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future<Integer> future = executor.submit(new MyCallable());
        
        try {
            Integer result = future.get();
            System.out.println("Sum: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        
        executor.shutdown();
    }
}

在这个例子中,我们通过Callable实现了一个简单的求和任务,并使用ExecutorService来管理线程执行。通过Future对象,我们可以获取线程执行的结果。 

2.4 线程池的使用

线程池是一种管理多个线程的工具,可以有效地减少线程的创建和销毁开销,提高资源利用率。Java通过ExecutorService提供了多种创建线程池的方式。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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

public class Main {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        for (int i = 0; i < 5; i++) {
            executor.submit(new MyRunnable());
        }
        
        executor.shutdown();
    }
}

在这个例子中,我们创建了一个固定大小的线程池,并向线程池提交了多个任务。线程池会合理分配线程来执行这些任务。

3. 线程的生命周期 

Java线程的生命周期包括多个状态,从线程的创建到终止,线程会经历不同的状态转换。理解线程的生命周期对于编写高效的多线程应用程序至关重要。

3.1 新建状态(New)

当一个线程对象被创建时,它处于新建状态。此时,线程对象已经存在,但还没有调用start()方法来启动线程。新建状态是线程生命周期的起始点,在这个状态下,线程还没有分配任何CPU资源。

Thread thread = new Thread(() -> {
    // Thread code here
});

3.2 就绪状态(Runnable)

当调用start()方法后,线程从新建状态进入就绪状态。在这个状态下,线程已经具备了运行的条件,等待操作系统调度器分配CPU时间片来执行。需要注意的是,在Java中,“就绪状态”并不意味着线程正在运行,而是等待被调度。

thread.start();  // Thread moves to the Runnable state

 线程调用start()后,立即进入就绪状态。操作系统的线程调度器会根据线程的优先级等条件,将就绪状态的线程分配到CPU上执行。

3.3 运行状态(Running)

当线程获得CPU时间片,开始执行run()方法中的代码时,线程进入运行状态。这是线程生命周期中唯一实际执行代码的状态。线程在这个状态下进行任务处理,直到被操作系统中断或自主放弃CPU资源。

@Override
public void run() {
    for (int i = 0; i < 5; i++) {
        System.out.println(Thread.currentThread().getName() + " - " + i);
    }
}

在这个例子中,线程进入运行状态并执行run()方法中的代码。运行状态通常非常短暂,因为操作系统会定期中断线程,以允许其他就绪线程获得执行机会。

3.4 阻塞状态(Blocked)

线程在执行过程中可能会因为某些原因(如等待资源、I/O操作、线程同步)而暂停运行,进入阻塞状态。在这个状态下,线程暂时放弃了CPU资源,直到满足特定条件(如获取锁或完成I/O操作),线程才能重新进入就绪状态。

阻塞状态可以进一步细分为以下几种:

  • 等待阻塞(Waiting Blocked):线程通过调用wait()方法进入等待队列,等待其他线程通过notify()notifyAll()方法唤醒它。

  • 超时等待阻塞(Timed Waiting Blocked):线程通过调用sleep(long millis)join(long millis)wait(long millis)等方法进入此状态,线程会在指定时间后自动苏醒,或在满足条件时被唤醒。

  • 同步阻塞(Synchronized Blocked):线程试图获取对象的同步锁,但该锁已被其他线程持有,此时线程进入同步阻塞状态。

synchronized (lock) {
    // Thread blocks if lock is held by another thread
}

 在这个例子中,线程试图获取锁对象lock,如果该锁被其他线程持有,当前线程将进入同步阻塞状态,直到锁可用。

3.5 终止状态(Terminated)

当线程的run()方法执行完毕或抛出未捕获的异常时,线程进入终止状态。此时,线程的生命周期结束,不能再重新启动。线程进入终止状态后,系统会释放线程所占用的所有资源。

thread.join();  // Waits for thread to die

调用join()方法后,主线程会等待thread线程终止后才继续执行。此时,thread线程已进入终止状态。

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

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

相关文章

解决ERROR: No matching distribution found for imp报错问题

一、问题描述 当我们使用Python3.4及其以上版本运行Python项目时&#xff0c;提示【ModuleNotFoundError: No module named imp】&#xff0c;但是我们使用【pip install imp】命令安装imp时却提示如下错误信息&#xff1a; ERROR: Could not find a version that satisfies t…

深入理解Java代理模式:从静态到动态的实现与应用

1、引言 在Java编程中&#xff0c;代理模式是一种常见的设计模式&#xff0c;用于在不修改原始代码的情况下&#xff0c;为对象添加额外的功能。代理模式有两种主要类型&#xff1a;静态代理和动态代理。本文将全面探讨这两种代理模式&#xff0c;包括它们的基本概念、实现方式…

增材制造(3D打印):为何备受制造业瞩目?

在科技浪潮的推动下&#xff0c;增材制造——即3D打印技术&#xff0c;正逐步成为制造业领域的璀璨新星&#xff0c;吸引了航空航天、汽车、家电、电子等众多行业的目光。那么&#xff0c;是什么让3D打印技术如此引人注目并广泛应用于制造领域&#xff1f;其背后的核心优势又是…

VSCODE SSH连接失败

前提&#xff1a;以前连接得好好的 突然有一天就连接不上了 打开C盘下的known_hosts文件删除如下内容&#xff0c;重新登陆即可

天正如何保存低版本

打开天正cad的界面。左边找到文件布图这个菜单&#xff0c;点击进入找到图形导出这个子菜单&#xff0c;之后会出现下面这一界面。 第2步 可以看到保存类型&#xff0c;一进去是天正3文件的&#xff0c;这时候你要点开下拉选择天正6文件&#xff0c;其它可以不用修o改&#x…

Keepalived和Nginx一起在Centos7上实现Nginx高可用设计

方案概览 如需详细信息可点击下列链接进行视频观看 B站 7分钟弄懂啥是高可用基石-VIP从零开始实操VIP 抖音 7分钟弄懂啥是高可用基石-VIP从零开始实操VIP Centos7 yum更新 安装阿里yum源 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Cent…

TCP/UDP的对比,粘包分包抓包,http协议

服务器端&#xff1a; 一、loop 127.0.0.1本地回环测试地址 二、tcp特点 面向连接、可靠传输、字节流 粘包问题&#xff1a;tcp流式套接字&#xff0c;数据与数据之间没有套接字&#xff0c;导致可能多次的数据粘到一起 解决方法&#xff1a;&#xff08;1&#xff09;规…

Linux数据相关第1个服务_备份服务rsync

1、备份服务概述 备份服务&#xff1a;需要使用到脚本&#xff0c;打包备份&#xff0c;定时任务 备份服务&#xff1a;rsyncd 服务&#xff0c;不同主机之间数据传输 特点: rsync是个服务也是命令使用方便&#xff0c;具有多种模式传输数据的时候是增量传输 增量与全量&am…

Nginx: 配置项之http模块connection和request的用法以及limit_conn和limit_req模块

connection和request connection 就是一个连接, TCP连接 客户端和服务器想要进行通信的话&#xff0c;有很多种方式比如说, TCP的形式或者是UDP形式的通常很多应用都是建立在这个TCP之上的所以, 客户端和服务器通信&#xff0c;使用了TCP协议的话&#xff0c;必然涉及建立TCP连…

一分钟告诉你毕业季大学都在用在线版招生简章是如何制作?

毕业季临近&#xff0c;各大高校纷纷进入招生宣传的关键时期。在数字化时代背景下&#xff0c;在线版招生简章成为了高校之间竞争的焦点。一分钟带你了解&#xff0c;这些吸引眼球的在线版招生简章是如何制作出来的。 1. 准备好制作工具&#xff1a;FLBOOK在线制作电子杂志平台…

【论文分享】Graviton: Trusted Execution Environments on GPUs 2018’OSDI

目录 AbstractIntroductioncontributions BackgroundGPUSoftware stackHardwareContext and channel managementCommand submissionProgramming modelInitializationMemory allocationHost-GPU transfersKernel dispatch Sharing Intel SGX Threat ModelOverviewGraviton Archi…

World of Warcraft [CLASSIC] Engineering 335-420

World of Warcraft [CLASSIC] Engineering 工程学冲技能点 335 - 420 [冰霜冲击雷管] 335-345 [冰霜手雷] 346-358 这部分知道可以不看了 在地狱火半岛&#xff0c;萨尔玛&#xff0c;找70级工程学大师学习新的技能&#xff0c;用来充技能都不划算 回【达拉然】找80级工程…

【电子数据取证】提升案件分析准确性的去重技术

前言 紧随《AES解密侵犯隐私案件数据》一文的讨论&#xff0c;本文将深入探讨数据解密后的处理工作。解密只是数据恢复的第一步&#xff0c;确保数据的准确性和分析的有效性同样重要。本文将重点介绍数据去重技术&#xff0c;阐述在解密数据后如何细致地进行去重处理&#xff…

wx.choosemedia 无反应 不生效 不弹出图片视频

调整开发者工具基础版本&#xff1a;打开微信开发者工具 > 右上方点击详情 > 本地设置 >调试基础库&#xff08;更换版本&#xff09; 这里我试了几个&#xff0c;发现 3 开头的版本都不行。。最后选了 2.30.4版本&#xff0c;官方文档给的答案是 2.10.0 开始支持 。…

特殊管道资源采购

管道资源物料是从管道&#xff08;如输油管&#xff09;或其它线管&#xff08;如输电线&#xff09;中直接进入生产流程的物料。与寄售物料不同的是&#xff0c;管道资源物料不必一定经过“采购”获得。管道库存不是在仓库中实际可用的库存。管道中的物料始终可用&#xff0c;…

Datawhale X 李宏毅苹果书 AI夏令营-深度学习入门班-task1

机器学习就是去拟合一种函数&#xff0c;它可能在高维上&#xff0c;十分抽象&#xff0c;但是却可以有丰富的语义含义&#xff0c;从而完成一系列任务 回归任务是预测一个准确的值&#xff0c;例如拟合一条直线的时候&#xff0c;我们希望每一个点的值都能对应上 分类任务则…

JAVA-抽象类和抽象方法

目录 一、抽象类的概念 二、抽象类语法 三、抽象类特性规则 四、抽象类的作用 一、抽象类的概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c;如果 一个类中没有包含足够…

宠物空气净化器是否是智商税?性价比高的宠物空气净化器十大排名

我开着一家猫咪咖啡馆&#xff0c;我们店貌美小猫可没少给我带来回头客~先给大家看看我的招财猫们 我的猫咪咖啡馆已经运营了三年了&#xff0c;直到最近才迎来了盈利的曙光。初期&#xff0c;面对种种困难与挑战&#xff0c;特别是频繁的投诉&#xff0c;几乎让我陷入了经营困…

IO进程线程8月23日

1&#xff0c;思维导图 2&#xff0c;创建子父 #include<myhead.h> int main(int argc, const char *argv[]) {pid_t pid;pidfork();if(pid>0){int fp3open("./3.txt",O_RDONLY);int fp4open("./4.txt",O_CREAT|O_TRUNC|O_WRONLY,0664);char str…

gin快速入门

gin 项目地址晓智科技晓智科技晓智文档晓智文档文档源码文档源码 快速体验 func HandlerPong(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",}) }func main() {r : gin.Default()r.GET("/ping", HandlerPong)_ r.Run(&qu…