Java多线程编程与并发处理

引言

在现代编程中,多线程和并发处理是提高程序运行效率和资源利用率的重要方法。Java提供了丰富的多线程编程支持,包括线程的创建与生命周期管理、线程同步与锁机制、并发库和高级并发工具等。本文将详细介绍这些内容,并通过表格进行总结和示范。

线程的创建与生命周期

使用Thread类

可以通过继承Thread类来创建线程,并重写其run方法。

public class MyThread extends Thread {public void run() {System.out.println("Thread is running.");}public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}

使用Runnable接口

实现Runnable接口并将其实例传递给Thread对象也是创建线程的一种方式。

public class MyRunnable implements Runnable {public void run() {System.out.println("Runnable is running.");}public static void main(String[] args) {MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();}
}

使用线程池

使用ExecutorService可以创建和管理线程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {Runnable worker = new MyRunnable();executor.execute(worker);}executor.shutdown();}
}

线程的生命周期

线程有以下几种状态:

  • 新建(New)
  • 就绪(Runnable)
  • 运行(Running)
  • 等待/阻塞/休眠(Waiting/Blocked/Sleeping)
  • 终止(Terminated)

线程同步与锁机制

同步方法

使用sychronized关键字可以同步方法,确保同一时刻只有一个线程可以访问该方法。

public class SynchronizedExample {private int count = 0;public synchronized void increment() {count++;}public static void main(String[] args) {SynchronizedExample example = new SynchronizedExample();example.increment();}
}

同步块

同步块使用sychronized关键字包围代码块,比同步方法更加灵活。

public class SynchronizedBlockExample {private int count = 0;private final Object lock = new Object();public void increment() {synchronized (lock) {count++;}}public static void main(String[] args) {SynchronizedBlockExample example = new SynchronizedBlockExample();example.increment();}
}

ReentrantLock

ReentrantLock提供了更加灵活的锁机制。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private int count = 0;private final Lock lock = new ReentrantLock();public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}public static void main(String[] args) {ReentrantLockExample example = new ReentrantLockExample();example.increment();}
}

并发库

Executor框架

Executor框架是Java并发库的核心部分,简化了并发任务的执行。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ExecutorExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(2);for (int i = 0; i < 5; i++) {executor.submit(() -> {System.out.println(Thread.currentThread().getName() + " is executing task.");});}executor.shutdown();}
}

Future和Callable

Callable接口表示一个可以返回结果的任务,Future接口表示异步计算的结果。

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;public class FutureCallableExample {public static void main(String[] args) {ExecutorService executor = Executors.newCachedThreadPool();Callable<Integer> task = () -> {Thread.sleep(2000);return 123;};Future<Integer> future = executor.submit(task);try {System.out.println("Result: " + future.get());} catch (InterruptedException | ExecutionException e) {e.printStackTrace();} finally {executor.shutdown();}}
}

高级并发工具

CountDownLatch

CountDownLatch允许一个或多个线程等待,直到其他线程完成一组操作。

import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {int count = 3;CountDownLatch latch = new CountDownLatch(count);for (int i = 0; i < count; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName() + " is running.");latch.countDown();}).start();}latch.await();System.out.println("All tasks completed.");}
}

CyclicBarrier

CyclicBarrier允许一组线程互相等待,直到所有线程都到达一个屏障点,然后继续执行。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) {int count = 3;CyclicBarrier barrier = new CyclicBarrier(count, () -> {System.out.println("All threads arrived. Let's continue...");});for (int i = 0; i < count; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName() + " is waiting.");try {barrier.await();} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}).start();}}
}

表格总结

线程的创建方法

创建方法描述示例
继承Thread类创建一个新的线程类,重写run方法class MyThread extends Thread { public void run() { ... } }
实现Runnable接口创建一个实现Runnable接口的类,实现run方法class MyRunnable implements Runnable { public void run() { ... } }
使用ExecutorService创建和管理线程池ExecutorService executor = Executors.newFixedThreadPool(5);

线程同步方法

同步方法描述示例
synchronized方法同步整个方法,只允许一个线程访问public synchronized void increment() { ... }
synchronized块同步代码块,只允许一个线程访问指定代码块synchronized (lock) { ... }
ReentrantLock显式锁机制,提供了更灵活的同步控制lock.lock(); try { ... } finally { lock.unlock(); }

并发工具

工具描述示例
CountDownLatch允许一个或多个线程等待,直到其他线程完成一组操作new CountDownLatch(count);
CyclicBarrier允许一组线程互相等待,直到所有线程都到达屏障点new CyclicBarrier(count, Runnable);
Executor框架简化并发任务的执行和管理ExecutorService executor = Executors.newFixedThreadPool(2);
Future和Callable表示异步计算和可返回结果的任务Future<Integer> future = executor.submit(task);

应用场景与实践:生产者-消费者模型

生产者-消费者模型是多线程编程中的经典问题。该模型中,通过使用BlockingQueue可以方便地实现线程之间的安全通信和协调,从而避免资源争用和死锁问题。

示例:生产者-消费者模型

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class ProducerConsumerExample {public static void main(String[] args) {BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);// 生产者Runnable producer = () -> {int value = 0;while (true) {try {queue.put(value);System.out.println("Produced: " + value);value++;Thread.sleep(500);  // 模拟生产时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};// 消费者Runnable consumer = () -> {while (true) {try {int value = queue.take();System.out.println("Consumed: " + value);Thread.sleep(1000);  // 模拟消费时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};new Thread(producer).start();new Thread(consumer).start();}
}

在以上示例中,BlockingQueue用作存储数据的共享缓冲区,生产者线程不断向队列中添加数据,而消费者线程从队列中取出数据进行处理。通过BlockingQueue的阻塞特性,生产者和消费者在队列满或空时自动等待,从而实现线程间的协调。

表格总结

线程的创建方法

创建方法描述示例
继承Thread类创建一个新的线程类,重写run方法class MyThread extends Thread { public void run() { ... } }
实现Runnable接口创建一个实现Runnable接口的类,实现run方法class MyRunnable implements Runnable { public void run() { ... } }
使用ExecutorService创建和管理线程池ExecutorService executor = Executors.newFixedThreadPool(5);

线程同步方法

同步方法描述示例
synchronized方法同步整个方法,只允许一个线程访问public synchronized void increment() { ... }
synchronized块同步代码块,只允许一个线程访问指定代码块synchronized (lock) { ... }
ReentrantLock显式锁机制,提供了更灵活的同步控制lock.lock(); try { ... } finally { lock.unlock(); }

并发工具

工具描述示例
CountDownLatch允许一个或多个线程等待,直到其他线程完成一组操作new CountDownLatch(count);
CyclicBarrier允许一组线程互相等待,直到所有线程都到达屏障点new CyclicBarrier(count, Runnable);
Executor框架简化并发任务的执行和管理ExecutorService executor = Executors.newFixedThreadPool(2);
Future和Callable表示异步计算和可返回结果的任务Future<Integer> future = executor.submit(task);

线程池与并发框架

Java并发编程中,线程池与并发框架是实现高效多线程的关键组件。线程池可以重复利用线程,减少线程创建和销毁的开销。而并发框架如java.util.concurrent包则提供了丰富的并发工具。

线程池示例:固定大小线程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class FixedThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(3);for (int i = 0; i < 5; i++) {executor.submit(() -> {System.out.println(Thread.currentThread().getName() + " is executing task.");try {Thread.sleep(1000);  // 模拟任务执行时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}executor.shutdown();}
}

在此示例中,使用Executors.newFixedThreadPool(int)方法创建一个固定大小的线程池,并提交多个任务供线程池执行。线程池能有效管理线程的创建和销毁,优化资源使用。

锁和同步机制

在多线程环境下,正确的锁和同步机制是防止数据竞争和确保数据一致性的关键。

ReentrantLock示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private int count = 0;private final Lock lock = new ReentrantLock();public void increment() {lock.lock();try {count++;System.out.println(Thread.currentThread().getName() + " count: " + count);} finally {lock.unlock();}}public static void main(String[] args) {ReentrantLockExample example = new ReentrantLockExample();Runnable task = example::increment;for (int i = 0; i < 5; i++) {new Thread(task).start();}}
}

在上述示例中,ReentrantLock用于显式锁机制,确保同一时刻只有一个线程能够访问共享数据。

结束语

本文详细介绍了Java中的多线程编程和并发处理,包括线程的创建与生命周期、线程同步与锁机制、并发库和高级并发工具等。通过代码示例和表格总结,希望您能更好地理解和应用Java的多线程编程,提高程序性能和资源利用率。

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

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

相关文章

IntelliJ IDEA 用maven创建web项目

前言 已经安装并配置好Tomcat。具体步骤&#xff1a;Tomcat安装及环境变量配置(一看就会)-CSDN博客​编辑https://blog.csdn.net/longyongyyds/article/details/135825647 具体步骤 1.新建一个maven项目 2&#xff0c;配置好tomcat服务器 3.运行测试一下 maven教程&#xf…

使用PHP对接企业微信审批接口的流程和基本接口(一)

在现代企业中&#xff0c;审批流程是非常重要的一环&#xff0c;它涉及到企业内部各种业务流程的规范和高效运转。而随着企业微信的流行&#xff0c;许多企业希望将审批流程整合到企业微信中&#xff0c;以实现更便捷的审批操作。本文将介绍如何使用PHP对接企业微信审批接口&am…

鸿蒙轻内核A核源码分析系列四(3) 虚拟内存

4.2 函数LOS_RegionAlloc 函数LOS_RegionAlloc用于从地址空间中申请空闲的虚拟地址区间。参数较多&#xff0c;LosVmSpace *vmSpace指定虚拟地址空间&#xff0c;VADDR_T vaddr指定虚拟地址&#xff0c;当为空时&#xff0c;从映射区申请虚拟地址&#xff1b;当不为空时&#…

WebSocket 详解--spring boot简单使用案例

一、什么是WebSocket WebSocket 是一种网络通信协议&#xff0c;专为在单个 TCP 连接上进行全双工通信而设计。WebSocket 允许客户端和服务器之间的消息能够实时双向传输。这与传统的 HTTP 请求-响应模式有很大的不同。 二、WebSocket 的关键特性 双向通信&#xff1a;WebSocke…

【StableDiffusion】Prompts 提示词语法;高阶用法;写作顺序是什么,先写什么后写什么

Prompt 写作顺序 第一步&#xff1a;画质词画风词 第一步先写“画质词”和“画风词” 画质词如下&#xff1a; 画风词如下&#xff1a; 第二步&#xff1a;画面主体描述 人物性别、年龄、发型、发色、情绪表情、衣服款式、衣服颜色、动作、饰品、身材、五官微调 第三步&…

多表联查小情景例子

这里有个需求&#xff1a; 需要给定套餐表setmeal 的 id 查询这个套餐内的所有菜品 dish 实际上如果可能&#xff0c;只需要查询套餐菜品表(setmeal_dish)&#xff0c;查看一个套餐内包含包含的所有菜品&#xff0c;然后把这些菜品全部取出即可。 看一下setmeal_dish 表&…

ZnO电阻片在低电场区域的泄漏电流及其电阻的负温度系数

在低电场区域,流过ZnO非线性电阻的泄漏电流小于1mA.泄漏电流不仅与施加的电压幅值有关,而且与温度高低有关。图2.6表示温度对泄漏电流的影响,温度越高,电子在电场作用下定向的运动就越激烈,导致泄漏电流增大。因此温度升高将导致电阳值下降,即ZnO 电阻呈现负温度特性。 一般以…

centos下创建raid6磁盘阵列

在CentOS系统中创建RAID 6阵列&#xff0c;可以使用mdadm工具。 以下是创建RAID 6阵列的基本步骤和示例代码&#xff1a; 安装mdadm工具&#xff08;如果尚未安装&#xff09;&#xff1a; sudo yum install mdadm 假设你有至少四个以上的磁盘设备&#xff08;例如 /dev/sdi…

STM32存储左右互搏 模拟U盘桥接SPI总线FATS读写FLASH W25QXX

STM32存储左右互搏 模拟U盘桥接SPI总线FATS读写FLASH W25QXX STM32的USB接口可以模拟成为U盘&#xff0c;通过FATS文件系统对连接的存储单元进行U盘方式的读写。 这里介绍STM32CUBEIDE开发平台HAL库模拟U盘桥接SPI总线FATS读写W25Q各型号FLASH的例程。 FLASH是常用的一种非易失…

maven archetype项目构架

1、设置环境变量 set MAVEN_HOMED:\SF\java\apache-maven-3.6.3 set path%path%;%MAVEN_HOME%\bin;2、制作archetype mvn -s "D:\SF\java\apache-maven-3.6.3\conf\settings.xml" archetype:create-from-project -DpackageNamecom.demo.esb-s:指定maven的setting文…

LeetCode | 28.找出字符串中第一个匹配项的下标 KMP

这是字符串匹配问题&#xff0c;朴素做法是两重遍历&#xff0c;依次从主串的i位置开始查看是否和模式串匹配&#xff0c;若不匹配就换下一个位置进行判断&#xff0c;直到找到或者遍历完&#xff0c;时间复杂度 O ( m n ) O(m \times n) O(mn) 还可以对主串进行处理&#xff…

vue.js+node.js+mysql在线聊天室源码

vue.jsnode.jsmysql在线聊天室源码 技术栈&#xff1a;vue.jsElement UInode.jssocket.iomysql vue.jsnode.jsmysql在线聊天室源码

单例模式、工厂模式 c++关键字 static

static 关键字的作用&#xff1a; 主要作用在于 控制变量或函数的作用域、生命周期以及它们如何被不同部分的程序访问&#xff0c;从而帮助程序员管理内存、避免命名冲突&#xff0c;并实现特定的设计模式&#xff08;如单例模式&#xff09;。 1. 静态局部变量&#xff1a;当…

区间预测 | Matlab实现EVO-CNN-SVM能量谷算法优化卷积神经网络支持向量机结合核密度估计多置信区间多变量回归区间预测

区间预测 | Matlab实现EVO-CNN-SVM能量谷算法优化卷积神经网络支持向量机结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现EVO-CNN-SVM能量谷算法优化卷积神经网络支持向量机结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资…

5.3 Python 闭包函数,递归函数,匿名函数

1. 函数对象 Python中所有的数据都是对象, 函数的值也是一个对象, 通过函数名获取函数对象. 使用函数名也就是使用函数对象, 函数对象加上括号立刻执行函数体代码块. 函数名的其它作用: * 1. 函数名可以作为其它变量的值. * 2. 函数名可以作为其它函数的参数. * 3. 函数名可以…

搜索与图论:染色法判别二分图

搜索与图论&#xff1a;染色法判别二分图 题目描述参考代码 题目描述 输入样例 4 4 1 3 1 4 2 3 2 4输出样例 Yes参考代码 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 100010, M 200010;int n, m; i…

多款可观测产品全面升级丨阿里云云原生 5 月产品月报

云原生月度动态 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 趋势热点 &#x1f947; 阿里云云原生产品负责人李国强&#xff1a;推进可…

《Brave New Words 》9.1 AI 世界中的就业

Part IX: Work and What Comes Next 第九部分&#xff1a;工作及其未来发展 The one who plants trees, knowing that he will never sit in their shade, has at least started to understand the meaning of life. —Rabindranath Tagore 种树的人&#xff0c;虽然知道他永远…

如何舒适的使用VScode

安装好VScode后通常会很不好用&#xff0c;以下配置可以让你的VScode变得好用许多。 VScode的配置流程 1、设置VScode中文2、下载C/C拓展&#xff0c;使代码可以跳转3、更改编码格式4、设置滚轮缩放5、设置字体6、设置保存自动改变格式7、vscode设置快捷代码8、下载插件并学会…