并发编程的深入探索(3/5)

目录

1. Java线程模型

示例代码:创建线程的两种方式

2. 同步机制与锁

示例代码:synchronized的使用

显式锁(ReentrantLock)

3. Java并发工具包(java.util.concurrent)

线程池(Executor Framework)

线程安全集合

4. Fork/Join框架

示例代码:Fork/Join框架

总结


并发编程的深入探索(3/5)

在现代计算机硬件中,多核处理器的普及让并发编程变得越来越重要。Java作为一种成熟的编程语言,提供了多种工具和API来帮助开发者编写高效的并发代码。这篇文章将深入探讨Java线程模型、同步机制、并发工具包(java.util.concurrent)以及Fork/Join框架,帮助你全面掌握Java的并发编程。

1. Java线程模型

Java线程模型是理解并发编程的核心。Java中的线程可以通过继承Thread类或实现Runnable接口来创建。

示例代码:创建线程的两种方式
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread running: " + Thread.currentThread().getName());
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable running: " + Thread.currentThread().getName());
    }
}

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

        Thread thread2 = new Thread(new MyRunnable());
        thread2.start();
    }
}

在上述代码中,MyThread通过继承Thread类实现,而MyRunnable通过实现Runnable接口实现。这两种方式都是创建线程的基本方法。

创建线程方式特性
继承Thread直接创建线程,简单但不支持多继承
实现Runnable接口支持实现多个接口,推荐使用

2. 同步机制与锁

在多线程环境中,多个线程可能会竞争共享资源,导致竞态条件(Race Condition)。为了解决这个问题,我们可以使用同步机制来确保线程安全。

Java提供了多种同步机制来解决共享资源的问题,包括synchronized关键字和显式锁(如ReentrantLock)。

示例代码:synchronized的使用
class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Final count: " + counter.getCount());
    }
}

在这个例子中,increment()方法使用了synchronized关键字,确保在多线程环境中只有一个线程能够同时执行该方法,从而保证了数据的安全性。

显式锁(ReentrantLock)

除了synchronized关键字,Java还提供了ReentrantLock类来实现显式锁定。

import java.util.concurrent.locks.ReentrantLock;

class LockCounter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        return count;
    }
}

ReentrantLock提供了更灵活的锁机制,比如支持中断和非阻塞地尝试获取锁。

3. Java并发工具包(java.util.concurrent)

Java 5引入了java.util.concurrent并发工具包,极大地简化了并发编程的难度。这些工具包包括线程池、同步工具类、并发集合等。

线程池(Executor Framework)

线程池是一种管理线程的机制,可以有效地提高性能并减少资源消耗。

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

public class ExecutorExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 5; i++) {
            executor.execute(() -> {
                System.out.println("Thread: " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

在这个例子中,我们创建了一个固定大小为3的线程池,通过execute()方法执行任务。线程池可以重用线程,从而减少线程创建和销毁的开销。

并发工具类用途
ExecutorService管理线程池,执行并发任务
CountDownLatch控制一个或多个线程等待多个操作完成
Semaphore控制对资源的并发访问
线程安全集合

java.util.concurrent包中提供了一些线程安全的集合,如ConcurrentHashMapCopyOnWriteArrayList,可以安全地在多线程环境中使用。

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentMapExample {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        map.put("A", 1);
        map.put("B", 2);

        map.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

在多线程环境中,ConcurrentHashMap可以提供更高的并发性和更好的性能,而不需要显式同步。

4. Fork/Join框架

Fork/Join框架是Java 7中引入的一个并行计算框架,用于将大任务拆分成多个小任务,并行执行以提高效率。ForkJoinPool是Fork/Join框架的核心类。

示例代码:Fork/Join框架
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

class SumTask extends RecursiveTask<Integer> {
    private final int[] arr;
    private final int start, end;
    private static final int THRESHOLD = 10;

    public SumTask(int[] arr, int start, int end) {
        this.arr = arr;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        if (end - start <= THRESHOLD) {
            int sum = 0;
            for (int i = start; i < end; i++) {
                sum += arr[i];
            }
            return sum;
        } else {
            int mid = (start + end) / 2;
            SumTask leftTask = new SumTask(arr, start, mid);
            SumTask rightTask = new SumTask(arr, mid, end);
            leftTask.fork();
            int rightResult = rightTask.compute();
            int leftResult = leftTask.join();
            return leftResult + rightResult;
        }
    }
}

public class ForkJoinExample {
    public static void main(String[] args) {
        int[] arr = new int[100];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }

        ForkJoinPool pool = new ForkJoinPool();
        SumTask task = new SumTask(arr, 0, arr.length);
        int result = pool.invoke(task);
        System.out.println("Sum: " + result);
    }
}

在这个例子中,我们使用RecursiveTask实现了一个任务,将数组分成小块并行求和。Fork/Join框架非常适合需要将大任务拆分为小任务的场景。

总结

在本篇文章中,我们深入探讨了Java中的并发编程,包含线程的创建、同步机制、并发工具包及Fork/Join框架。并发编程是一个复杂但非常重要的主题,尤其在当前的多核处理器环境下,掌握Java的并发编程工具可以大大提升代码的执行效率和响应能力。

在接下来的文章中,我们将讨论Java性能调优与垃圾回收机制,帮助你理解如何进一步提升Java应用的性能。希望通过这篇文章的学习,你对Java的并发编程有了更深入的理解,并能够在项目中灵活运用这些知识。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gcc与mingw64版本介绍

三类编译器 GCC&#xff0c;全称为GNU Compiler Collection&#xff0c;是一个强大的编译器集合&#xff0c;它不仅支持C和C语言&#xff0c;还支持Fortran、Ada、Java等多种编程语言的编译。在GCC工具链中&#xff0c;gcc和g是两个核心的编译器工具。gcc是专门用于编译C语言程…

PostgreSQL使用clickhouse_fdw访问ClickHouse

Postgres postgres版本&#xff1a;16&#xff08;测试可用&#xff09;docker 安装 插件安装 clickhouse_fdw: https://github.com/ildus/clickhouse_fdw 安装命令 git clone gitgithub.com:ildus/clickhouse_fdw.git cd clickhouse_fdw mkdir build && cd build…

【高级IO】IO多路转接之epoll

epoll接口 epoll_create 创建一个epoll模型 自从linux2.6.8之后&#xff0c;size参数是被忽略的返回值是一个文件描述符用完之后, 必须调用close()关闭 epoll_ctl epoll_ctl用于添加、修改或删除关注的文件描述符&#xff0c;并设置感兴趣的事件类型&#xff08;如读事件、写…

windows 11 mpksldrv.sys 导致蓝屏

#mpksldrv.sys 导致蓝屏 windows 11 在运行Twincat 3进行仿真时&#xff0c;就会蓝屏 尝试了各种其他的办法修改什么注册表&#xff0c;各种办法都尝试了没有用&#xff0c; 后面尝试了下面的办法竟然解决了&#xff0c;请参考下面链接&#xff1a; 链接: 两条命令可以帮助你…

如何使用的是github提供的Azure OpenAI服务

使用的是github提供的Azure OpenAI的服务gpt-4o 说明&#xff1a;使用的是github提供的Azure OpenAI的服务&#xff0c;可以无限薅羊毛。开源地址 进入&#xff1a; 地址 进入后点击 右上角“Get API key”按钮 点击“Get developer key” 选择Beta版本“Generate new to…

WPF+MVVM案例实战(九)- 霓虹灯字效果控件封装实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、运行效果2、主菜单与界面实现1、主菜单2、霓虹灯字界面实现3、字体资源获取3、控件封装1.创建自定义控件2、依赖属性实现3、封装控件使用4、运行效果4、源代码获取1、运行效果 2、主菜单与界面实…

Vulkan 开发(五):Vulkan 逻辑设备

图片来自《Vulkan 应用开发指南》 Vulkan 开发系列文章&#xff1a; 1. 开篇&#xff0c;Vulkan 概述 2. Vulkan 实例 3. Vulkan 物理设备 4. Vulkan 设备队列 在 Vulkan 中&#xff0c;逻辑设备&#xff08;Logical Device&#xff09;是与物理设备&#xff08;Physical D…

Hue3.9.0-cdh5.14.0安装

hue的安装需要准备如下的前置条件 1、Java-jdk8 2、python2.6 3、安装时非root用户 4、另行安装maven和ant&#xff0c;并配置HOME 5、hue安装节点需要hadoop、hive的配置文件 6、准备一个mysql库来做hue的元数据库 第一步&#xff1a;前置准备中的Javajdk和python准备本简单就…

自动驾驶-传感器简述

自动驾驶车辆上的传感器类型包含激光雷达、毫米波雷达、相机、imu、rtk、超声波雷达等&#xff0c;这些传感器用来接收外部世界多姿多彩的信号&#xff0c;根据接收到的信号&#xff0c;车载大脑对信号进行处理&#xff0c;那信号的准确程度就尤为重要。 本文将各个传感器的特性…

OpenCV图像处理方法:腐蚀操作

腐蚀操作 前提 图像数据为二值的&#xff08;黑/白&#xff09; 作用 去掉图片中字上的毛刺 显示图片 读取一个图像文件&#xff0c;并在一个窗口中显示它。用户可以查看这个图像&#xff0c;直到按下任意键&#xff0c;然后程序会关闭显示图像的窗口 # cv2是OpenCV库的P…

HarmonyOS开发 - 本地持久化之实现LocalStorage支持多实例

用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。数据存储形式为键值对&#xff0c;键的类型为字符串型&#xff0c;值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。 在上一篇中&…

深度学习Pytorch-Tensor的属性、算术运算

深度学习Pytorch-Tensor的属性、算术运算 Tensor的属性Tensor的算术运算Pytorch中的in-place操作Pytorch中的广播机制Tensor的取整/取余运算Tensor的比较运算Tensor的取前k个大/前k小/第k小的数值及其索引Tensor判定是否为finite/inf/nan Tensor的属性 每一个Tensor对象都有以…

记录一个容器间访问不通问题

docker-compose装了zookeeper和一个服务。 zk服务如下&#xff1a; szxc-zk:image: "image.sd001.cn:30003/base/zookeeper:3.8"privileged: trueenvironment:- "TZAsia/Shanghai"#- "ALLOW_ANONYMOUS_LOGINyes"- "ZOO_MY_ID1"- &qu…

vue+spreadjs开发

创建vue3项目 pnpm create vite --registryhttp://registry.npm.taobao.org安装spreadjs包 pnpm install "grapecity-software/spread-sheets17.1.7" "grapecity-software/spread-sheets-resources-zh17.1.7" "grapecity-software/spread-sheets-vu…

使用pytest单元测试框架执行单元测试

Pytest 是一个功能强大且灵活的 Python 单元测试框架&#xff0c;它使编写、组织和运行测试变得更加简单。以下是 Pytest 的一些主要特点和优点&#xff1a; 简单易用&#xff1a;Pytest 提供了简洁而直观的语法&#xff0c;使编写测试用例变得非常容易。它支持使用 assert 语…

WPF+MVVM案例实战(十)- 水波纹按钮实现与控件封装

文章目录 1、运行效果1、封装用户控件1、创建文件2、依赖属性实现2、使用封装的按钮控件1.主界面引用2.按钮属性设置3 总结1、运行效果 1、封装用户控件 1、创建文件 打开 Wpf_Examples 项目,在 UserControlLib 用户控件库中创建按钮文件 WaterRipplesButton.xaml ,修改 Us…

使用DeepLabV3实现植叶病害检测

实战 | 使用DeepLabV3实现植叶病害检测 数据集 数据集下载地址 训练后的数据集地址 如果打不开可以去我的资源下载 演示 原文章 原文章及原代码基础代码 我对源代码进行适配也可以找我要我改过的代码进行学习 我的代码

全国产 V7 690T+FT6678 高性能实时信号处理平台设计原理

1、概述 全国产 V7 690TFT6678 高性能实时信号处理平台组成如图 1 所示&#xff0c;包含 1 片SMQ7VX690TFFG1761 和两片 FT-6678&#xff08;国防科大&#xff09;的 DSP&#xff0c;总共 3 个主芯片&#xff1b;每个主芯片外部各搭配 1 组 64bit 的 DDR3 内存模组以及各芯片启…

安装双系统后ubuntu无法联网(没有wifi标识)网卡驱动为RTL8852BE

安装双系统后ubuntu没有办法联网&#xff0c;&#xff08;本篇博客适用的版本为ubuntu20.04&#xff09;且针对情况为无线网卡驱动未安装的情况 此时没有网络&#xff0c;可以使用手机数据线连接&#xff0c;使用USB共享网络便可解决无法下载的问题。 打开终端使用命令lshw -C …

cesium 加载本地json、GeoJson数据

GeoJSON是一种用于编码地理数据结构的格式 {"type": "Feature","geometry": {"type": "Point","coordinates": [125.6, 10.1]},"properties": {"name": "某地点"} } 一、直接加载…