当前位置: 首页 > news >正文

深入理解Java中的并发编程

深入理解Java中的并发编程:从基础到高级 并发编程是Java开发中的一项重要技能,它能提升程序的性能和响应能力。本文将从基础概念出发,逐步介绍Java中的并发编程,涵盖线程、同步机制以及高级并发工具。

  1. 基础概念
    线程
    线程是Java并发编程的基本单位,每个Java程序至少有一个线程,即主线程(main thread)。创建线程的两种主要方法是继承Thread类和实现Runnable接口。

继承Thread类

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

实现Runnable接口

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

同步机制
在并发编程中,多个线程可能会访问共享资源,导致数据不一致的问题。Java提供了多种同步机制来解决这一问题。

synchronized关键字
synchronized关键字用于方法或代码块,确保同一时间只有一个线程可以执行该方法或代码块。

class Counter {private int count = 0;public synchronized void increment() {count++;}public int getCount() {return count;}
}

ReentrantLock
ReentrantLock提供了更灵活的同步机制,可以替代synchronized关键字。

import java.util.concurrent.locks.ReentrantLock;class Counter {private int count = 0;private ReentrantLock lock = new ReentrantLock();public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}public int getCount() {return count;}
}
  1. 高级并发工具
    Java的java.util.concurrent包提供了许多高级并发工具,简化了复杂的并发任务。

Executor框架
Executor框架是Java 5引入的一种线程池机制,简化了线程的管理和调度。

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

Callable和Future
Callable接口与Runnable类似,但它可以返回结果并抛出异常。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 Main {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);Callable<Integer> task = () -> {return 123;};Future<Integer> future = executor.submit(task);try {Integer result = future.get();System.out.println("Result: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}executor.shutdown();}
}

并发集合
java.util.concurrent包还提供了一些线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等。

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class Main {public static void main(String[] args) {ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();map.put("key", 1);map.computeIfPresent("key", (k, v) -> v + 1);System.out.println("Value for 'key': " + map.get("key"));}
}
  1. 实战示例:生产者-消费者模式
    生产者-消费者模式是经典的并发编程问题。下面是一个简单的生产者-消费者示例,使用BlockingQueue实现。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class Producer implements Runnable {private BlockingQueue<Integer> queue;public Producer(BlockingQueue<Integer> queue) {this.queue = queue;}public void run() {for (int i = 0; i < 10; i++) {try {System.out.println("Produced: " + i);queue.put(i);Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}
class Consumer implements Runnable {private BlockingQueue<Integer> queue;public Consumer(BlockingQueue<Integer> queue) {this.queue = queue;}public void run() {try {while (true) {Integer value = queue.take();System.out.println("Consumed: " + value);Thread.sleep(150);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}
public class Main {public static void main(String[] args) {BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);Thread producerThread = new Thread(new Producer(queue));Thread consumerThread = new Thread(new Consumer(queue));producerThread.start();consumerThread.start();}
}

结论
并发编程是Java开发中的一项核心技能。本文从线程的基本概念出发,逐步介绍了同步机制和高级并发工具,最后通过生产者-消费者模式示例展示了如何在实际应用中使用这些知识。掌握并发编程,不仅可以提升程序的性能,还能提高代码的可维护性和扩展性。

这里是引用

相关文章:

  • 【LeetCode215】数组中的第K个最大元素
  • 爆赞!GitHub首本Python开发实战背记手册,标星果然百万名不虚传
  • Ant-Design-Vue动态表头并填充数据
  • vue3写一个定时器
  • Kantana和The Sandbox联手打造元宇宙娱乐的未来
  • Android开启HTTP服务
  • 微服务必备容器化技术
  • LUA移植到STM32F4,移植REPL,通过RTT Viewer交互
  • GraogGNSSLib学习
  • 医学人工智能在“免疫组化”领域的最新研究进展|顶刊速递·24-06-19
  • 美业人专用宝藏系统、Java收银系统源码分享-美业SAAS系统的应用价值分析
  • 关于INCA的几个实用功能
  • Top10在线音频剪辑软件,你了解几款?(免费分享)
  • 前端技术回顾系列 11|TS 中一些实用概念
  • Android C++系列:函数知识知多少
  • 「译」Node.js Streams 基础
  • 230. Kth Smallest Element in a BST
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • co.js - 让异步代码同步化
  • javascript数组去重/查找/插入/删除
  • Java反射-动态类加载和重新加载
  • Linux CTF 逆向入门
  • magento 货币换算
  • Making An Indicator With Pure CSS
  • node.js
  • Swoft 源码剖析 - 代码自动更新机制
  • tensorflow学习笔记3——MNIST应用篇
  • 关于Flux,Vuex,Redux的思考
  • 关于Java中分层中遇到的一些问题
  • 今年的LC3大会没了?
  • 项目管理碎碎念系列之一:干系人管理
  • 一些关于Rust在2019年的思考
  • 主流的CSS水平和垂直居中技术大全
  • - 转 Ext2.0 form使用实例
  • 1.Ext JS 建立web开发工程
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 关于Android全面屏虚拟导航栏的适配总结
  • %@ page import=%的用法
  • (2)STM32单片机上位机
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (剑指Offer)面试题34:丑数
  • (图)IntelliTrace Tools 跟踪云端程序
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)C#调用WebService 基础
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • ..回顾17,展望18
  • .JPG图片,各种压缩率下的文件尺寸
  • .NET WPF 抖动动画
  • .NET 动态调用WebService + WSE + UsernameToken
  • .net 发送邮件
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • @FeignClient注解,fallback和fallbackFactory
  • @SpringBootApplication 包含的三个注解及其含义
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现