Java 的多线程浅析

news2024/11/23 20:20:29

在这里插入图片描述

前言

Java 的多线程在当今业界已经成为了一个非常重要的技能。无论您是新手还是经验丰富的程序员,精通 Java 的多线程编程都是至关重要的。因为多线程可以帮助您实现更快的应用程序、更高效的性能以及更出色的用户体验。在这篇文章中,我们将介绍有关 Java 多线程的全部细节,让您成为一名多线程编程高手。

Java 中的多线程概述

在 Java 中,多线程是同时进行多个任务的一种机制。一个线程是程序执行中的一个单独的控制路径。在创建线程时,您可以使用 Java 的多线程库中的类和方法。这个库提供了一些方法和类,可以帮助您实现一个多线程程序。

在 Java 中,线程由 Thread 类表示。一个线程是单独的执行路径,由 CPU 调度器决定何时调用该线程。每个线程都有自己的字节码指令堆栈、局部变量、寄存器和程序计数器。您可以使用 Thread 类的方法来启动、暂停、恢复和停止线程。

Java 多线程的三种实现方式

在 Java 中,有三种实现多线程的方式。它们分别是继承 Thread 类、实现 Runnable 接口和实现 Callable 接口。下面我们将详细讨论这三种方式。

1. 继承 Thread 类

Java 中的线程是由 Thread 类表示的。您可以继承 Thread 类并重写 run() 方法来实现一个线程。线程中的 run() 方法是线程代码的入口点。当您启动线程并调用它的 start() 方法时,Java 程序就开始执行线程的 run() 方法。下面是一个简单的继承 Thread 类的示例:

class MyThread extends Thread {
    public void run() {
        System.out.println("My thread started.");
    }
}

2. 实现 Runnable 接口

在实现线程时,您还可以实现 Runnable 接口。Runnable 接口定义了一个可运行类的标准接口。Runnable 接口的 run() 方法是线程代码的主体。您需要在 run() 方法中实现线程的逻辑。下面是一个简单的实现 Runnable 接口的示例:

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("My runnable started.");
    }
}

3. 实现 Callable 接口

在 Java 5 中,出现了一个新的 Callable 接口,通过实现 Callable 接口来编写多线程程序。Callable 接口也可以像 Runnable 接口一样被线程执行,不同之处在于,Callable 接口会返回一个带返回值的对象。下面是一个简单的实现 Callable 接口的示例:

class MyCallable implements Callable<String> {
    public String call() throws Exception {
        return "My callable started.";
    }
}

Java 多线程中使用 synchronized

在 Java 中,当多个线程访问一个共享资源时,您需要确保它是同步的。您可以使用 synchronized 关键字来实现同步。 synchronized 关键字会锁定指定对象,并确保其他线程无法访问它,直到当前锁被释放。下面是一个简单的使用 synchronized 的例子:

class Shared {
    private int sharedVariable;
    public synchronized void increment() {
        sharedVariable++;
    }
}

在这个例子中,我们使用 synchronized 关键字来确保 increment() 方法只会被一个线程访问。这确保了线程安全,并防止了并发问题。

Java 中的线程池

Java 中的线程池是一种机制,它允许您为多个线程分配和管理 CPU 资源。线程池通常在多线程环境中使用,以避免创建过多的线程而导致系统资源的浪费。在 Java 中,可以使用 Executors 标准类库来创建和管理线程池。 Executors 库提供了一些方法例如 newFixedThreadPool() 和 newCachedThreadPool() 等,可以帮助您实现不同类型的线程池。

下面是一个在 Java 中使用 Executor 创建线程池并提交任务的示例:

Executor executor = Executors.newFixedThreadPool(10);
executor.execute(new MyTask1());
executor.execute(new MyTask2());

在这个示例中,我们使用了一个固定大小的线程池,可以同时运行 10 个任务。然后我们使用 execute() 方法向线程池提交了两个任务。

Java 多线程中的死锁

在 Java 中,线程死锁是一个常见的问题。当两个或多个线程相互等待对方释放它们所需要的资源时,就会发生死锁。这种情况可能会导致多个线程被永久挂起,从而导致程序不能正常执行。下面是一个示例,展示了如何导致死锁:

class DeadlockExample {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();
    public void firstMethod() {
        synchronized(lock1) {
            System.out.println(Thread.currentThread() + " acquired lock1.");
            synchronized(lock2) {
                System.out.println(Thread.currentThread() + " acquired lock2.");
            }
        }
    }
    public void secondMethod() {
        synchronized(lock2) {
            System.out.println(Thread.currentThread() + " acquired lock2.");
            synchronized(lock1) {
                System.out.println(Thread.currentThread() + " acquired lock1.");
            }
        }
    }
}

在这个示例中,我们创建了两个锁 lock1 和 lock2,并在 firstMethod() 和 secondMethod() 方法中使用它们。当一个线程在 firstMethod() 中获取 lock1 之后想要继续获取 lock2,而另一个线程在 secondMethod() 中获取 lock2 后想要获取 lock1,就会导致死锁的出现。

Java 多线程中的异常处理

在多线程编程中,异常处理是非常重要的。如果您的程序中使用了多个线程,一个线程的异常可能会影响整个程序,因此您应该正确地处理异常。在 Java 中,可以使用 try-catch-finally 语句块来捕获异常。下面是一个示例:

class MyThread extends Thread {
    public void run() {
        try {
            // 代码在这里执行
        }
        catch (Exception ex) {
            // 捕获异常并进行处理
        }
        finally {
            // 清理资源
        }
    }
}

在这个示例中,我们使用了 try-catch-finally 语句块来捕获异常。在 run() 方法中,可以编写业务逻辑代码,并在需要时进行异常处理。
在这里插入图片描述

Java 多线程中的锁

在 Java 中,锁是一种机制,它允许您控制多个线程访问共享资源的方式。当多个线程都需要访问共享资源时,您需要确保它是同步的。您可以使用 Java 的锁机制来实现同步。在 Java 中,锁有两种类型:内部锁和外部锁。内部锁也称为 synchronized 块或重入锁,它们通过同步方法和同步代码块实现。下面是一个使用内部锁的简单示例:

class MyRunnable implements Runnable {
    private final Object lock = new Object();
    public void run() {
        synchronized(lock) {
            // 代码在这里执行
        }
    }
}

在这个示例中,我们使用了 synchronized 关键字来获取一个内部锁。然后,在同步块中,您可以编写线程的逻辑代码。

另一种类型的锁是外部锁,它由 Java 中的 java.util.concurrent.locks.Lock 接口表示。Lock 接口定义了一个可重入的互斥锁,可以使用它来控制对共享资源的访问。下面是一个简单的使用 Lock 接口的示例:

class MyRunnable implements Runnable {
    private final Lock lock = new ReentrantLock();
    public void run() {
        lock.lock();
        try {
            // 代码在这里执行
        }
        finally {
            lock.unlock();
        }
    }
}

在这个示例中,我们使用了 Lock 接口来获取一个外部锁。由于 Lock 接口不同于 synchronized 关键字,因此您需要在 finally 块中释放锁。

结论

Java 多线程编程是一个重要的技能。在这篇文章中,我们介绍了有关 Java 多线程的所有细节,从创建线程到在多线程环境中使用锁、线程池和异常处理。这些知识可以帮助您成为一名多线程编程高手,并允许您编写更快、更有效的代码,提高应用程序的性能和用户体验。

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

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

相关文章

【资料分享】PLC中输入输出端子

PLC输入输出分为高速和低速&#xff0c;一般来说不会超出&#xff0c;隔离器MOS的设计。其中具体采用光耦隔离还是数字隔离器隔离&#xff0c;其隔离器件会限制其输入输出的速率&#xff1b;PLC的源型和漏型就取决于最后末端所接的MOS管是如何布置的。 MOS管的源极和漏极 MOS…

Java 注解配合Spring AOP 导入Excel文件

Java 注解配合Spring AOP 导入Excel文件 这个就是把上一篇&#xff0c;封装了一层&#xff1b;根据注解中配置的变量名和方法名&#xff0c;通过JoinPoint获取到对应的对象和方法 注解 import static java.lang.annotation.ElementType.METHOD; import static java.lang.ann…

02 Redis经典五种数据类型介绍及落地运用

命令大全9大类型 String(字符类型)Hash(散列类型)List(列表类型)Set(集合类型)SortedSet(有序集合类型&#xff0c;简称zset)Bitmap(位图)HyperLogLog(统计)GEO(地理)Stream&#xff08;了解&#xff09; string 常用命令 最常用 set key valueget key 同时设置/获取多个键…

Spring之状态机讲解

文章目录 1 状态机1.1 什么是状态1.2 四大概念1.3 状态机1.4 spring statemachine 2 示例Demo2.1 订单状态图2.2 建表2.3 依赖和配置2.3.1 pom.xml2.3.2 application.yml 2.4 状态机配置2.4.1 定义状态机状态和事件2.4.2 定义状态机规则2.4.3 配置持久化2.4.3.1 持久化到内存2.…

畅游星河的炫彩手柄,配置也不简单,北通阿修罗2Pro上手

平时在PC上玩个游戏&#xff0c;还是手柄更好用。在国产的手柄里面&#xff0c;北通的很多人都用&#xff0c;选择比较多&#xff0c;价格相对也更加亲民一些&#xff0c;之前看到北通阿修罗2Pro新出了一款无线星河版本&#xff0c;做得很好看&#xff0c;上周到手后试了试&…

元宇宙,开启下一个消费Z时代

元宇宙到底怎么了&#xff1f;为什么国外一片唱衰&#xff0c;而国内却依旧不遗余力的积极推动&#xff1f;接下来&#xff0c;国内元宇宙又将带来怎样的机遇&#xff1f; 此时此刻&#xff0c;元宇宙被一味吹捧的阶段已经过去&#xff0c;取而代之的是并存的唱衰声与叫好声&a…

《Opencv3编程入门》学习笔记—第三章

《Opencv3编程入门》学习笔记 记录一下在学习《Opencv3编程入门》这本书时遇到的问题或重要的知识点。 第三章 HighGUI图形用户界面初步 一、图像的载入、显示和输出到文件 &#xff08;一&#xff09;OpenCV的命名空间 简单的OpenCV程序标配&#xff1a; #include <o…

如何利用Citespace和vosviewer既快又好地写出高质量的论文及快速锁定热点和重点文献进行可视化分析

文献计量学是指用数学和统计学的方法&#xff0c;定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体&#xff0c;注重量化的综合性知识体系。特别是&#xff0c;信息可视化技术手段和方法的运用&#xff0c;可直观的展示主题的研究发展历程、研究现状、研究…

Oracle实现主键字段自增

Oracle实现主键自增有4种方式&#xff1a; Identity Columns新特性自增&#xff08;Oracle版本≥12c&#xff09; 创建自增序列&#xff0c;创建表时&#xff0c;给主键字段默认使用自增序列 创建自增序列&#xff0c;使用触发器使主键自增 创建自增序列&#xff0c;插入语句&…

都2023年了,你竟然还不知道网络安全该怎么学!

前言 网络安全是指网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然或恶意原因而遭受破坏、更改、泄露&#xff0c;系统连续可靠正常地运行&#xff0c;网络服务不中断。 网络安全因何而重要&#xff1f; 截至2022年6月,我国网民规模为10.51亿&#xff0c…

nodejs 中使用websocket 并且区分空间,实现收到客服端消息 同步给房间内所有连接,小程序中使用websocket,区分房间、空间

❤️砥砺前行&#xff0c;不负余光&#xff0c;永远在路上❤️ 目录 前言一、服务端1、主要是通过nodeexpresswebsocket搭建2、代码大概结构3、nodejs 启动入口文件 引入自己的websocket文件&#xff0c;这里是为了和 http 服务结合起来&#xff0c;将server传入4、websocket.j…

【课代表笔记】直播回顾:Top药企的数字化实践集锦

【K讲了】系列直播之医药行业第一期&#xff1a;Top药企的数字化实践集锦前不久已在视频号和大家如期见面&#xff0c;以下是课代表为大家抄好的笔记~~ 斯歌K2的医药行业经验 K2在医药领域拥有丰富的客户积累及实施经验&#xff0c;全球TOP 10药企中有7家选择K2。斯歌K2已在医药…

JAVA POI excel 添加下拉字典的方式与案例 以及图文详解及个人理解

场景 原有的Excel 某一个 sheet 页中某些列需要添加指定的字典下拉&#xff0c;而这些字典的值又是确认的。 有两种思路&#xff1a; 一、如果给定的下拉字典值是确定的而且关联原有列的位置也不会变&#xff0c;那么这些数据可以固定写死在代码中&#xff0c;也是最简单的一…

身份集权设施保护之Kerberos协议

一、Kerberos协议介绍 Kerberos是一种由MIT&#xff08;麻省理工大学&#xff09;提出的一种网络身份验证协议。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。该认证过程的实现不依赖于主机操作系统的认证&#xff0c;无需基于主机地址的信任&#xff0…

Live800:新的消费趋势下,企业在线客服需哪些改变?

从2021到2023&#xff0c;新模式、新业态、新产业层出不穷&#xff0c;新兴习惯也不断涌现&#xff0c;我们见证了消费品牌的“新物种爆炸”&#xff0c;见证了各行业的线上迁移。 这一切催化消费市场持续更新&#xff0c;消费趋势演变的路径也发生了变化&#xff0c;从以前的…

“数字”厨电成新宠?“小米卷出光学拍摄“天花板”?|3C数码行业SMI社媒心智品牌榜

手机行业SMI社媒心智品牌榜核心解读 智能手机“乍暖还寒”&#xff0c;龙头品牌仍稳占消费者心智 比拼屏幕、赶超系统、迭代形态、拓展概念&#xff1f;眼花缭乱过后&#xff0c;产品精益求精&#xff0c;建立稳固的消费者认知&#xff0c;才是“保鲜”关键。在最新发布的数说…

趣味LFS实验部署

LFS文件准备 LFS项目官方网站&#xff1a;https://www.linuxfromscratch.org/ 查找宿主系统必须安装的软件包 https://www.linuxfromscratch.org/lfs/downloads/stable/LFS-BOOK-11.1-NOCHUNKS.html 安装依赖&#xff1a; #先来看看我此处的Yum仓库环境&#xff1a; CentOS-…

ArcGis系列-java调用GP分析

1,实现流程 创建GPServer,使用ArcgisPro添加GP工具运行,然后使用共享web服务发布运行成功的GP任务根据发布成功的GPServer发布地址&#xff0c;解析出GP服务的输入参数和输出参数前端输入gp服务需要的参数&#xff0c;发送给后端来异步提交后端提交后创建轮询任务等待执行结果…

3D知识入门

3D场景必备&#xff1a;scene, renderer, light, camera, model 一个基本代码: <script src"https://cdn.bootcdn.net/ajax/libs/three.js/r127/three.min.js"></script>var scene new THREE.Scene();var camera new THREE.PerspectiveCamera(75,windo…

【EKS】基于Amazon EKS搭建kubernetes集群

文章目录 前言 | 亚马逊云科技 re:Invent前沿资讯一、介绍篇&#x1f3a8;什么是AWS 云计算什么是Amazon EKS 二、部署篇&#x1f528;1、创建集群VPC2、创建集群子网3、创建IGW网关4、创建路由表与子网绑定5、EKS集群创建6、创建kubeconfig配置文件7、添加计算节点组8、查看EK…