Java 多线程加法求和

Java 多线程加法求和

代码

先上代码再上解析:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;public class Sum implements Runnable {private final int[] numbers;private final int start;private final int end;private final AtomicInteger total;public Sum(int[] numbers, int start, int end, AtomicInteger total) {this.numbers = numbers;this.start = start;this.end = end;this.total = total;}@Overridepublic void run() {int localSum = 0;for (int i = start; i < end; i++) {localSum += numbers[i];}// addAndGet 可以原子地(即线程安全地)将给定的数值增加到当前数值System.out.printf("local %d\n", localSum);total.addAndGet(localSum);}
}class MultiThreadedAddition {public static void main(String[] args) throws InterruptedException {// 实现从1加到100int[] numbers = new int[101];for (int i = 1; i < numbers.length; i++) {numbers[i] = i;}AtomicInteger total = new AtomicInteger();// 假设有4个线程并发计算int threadCount = 4;// Executors.newFixedThreadPool 用于创建一个固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(threadCount);// 把 numbers.length 个(100个)任务均分给 threadCount 个(4个)线程int partitionSize = numbers.length / threadCount;for (int i = 0; i < threadCount; i++) {int startIndex = i * partitionSize;// 这里要特判一下最后一个线程的结束范围,因为可能不能恰好均分任务,比如999个任务给4个线程做...int endIndex = (i == threadCount - 1) ? numbers.length : (i + 1) * partitionSize;Sum task = new Sum(numbers, startIndex, endIndex, total);executorService.submit(task);}// 先关闭线程池executorService.shutdown();// 阻塞主线程,让其等待所有线程提交结果(或者直到超过最大等待时间,不过这里设置的是MAX_VALUE,就是无限等待executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);System.out.println(total.get());}
}

运行结果

这里是做了一个1~100的求和,我们知道结果是5050,运行检验一下:
Java 多线程 加法求和1到100

多线程的要点解析

多线程创建:Runnable Callable Thread

Runnable 接口
  1. 基本概念
    Runnable 是一个非常基础的接口,只有一个方法 void run()。任何实现了 Runnable 接口的类都可以作为一个线程的工作单元(任务)。
  2. 传递给 Thread 类的构造函数
    当一个 Runnable 实例被传给 Thread 构造函数时,可以创建一个新的线程,然后调用 Thread.start() 方法启动该线程来执行 run() 方法中的代码。
  3. 没有返回值
    Runnable 不支持返回值,并且在 run() 方法内部抛出的异常不会被捕获并转发给调用者。
Thread 类
  1. 基本概念
    Thread 是Java中用于实现线程的基础类,它实现了 Runnable 接口,所以可以通过继承 Thread 类并重写 run() 方法来创建一个可运行的线程。
  2. 接收 Runnable 实例

呼应上文

通过创建 Thread 类的子类或通过传递一个 Runnable 对象给 Thread 构造函数,可以创建和管理线程。
3. 更多 API
Thread 类提供了更多控制线程生命周期的方法,如 start()、join()、interrupt()、setName() 等。

Callable 接口
  1. 基本概念
    Callable 是在Java 1.5以后引入的,相比于 Runnable,它更加灵活。

  2. 能返回值和抛出异常
    可以通过 call() 方法返回一个结果,而且 call() 方法可以抛出受检异常(checked exception)。

3. 使用
Callable 实例不能直接启动,需要通过 ExecutorService 提交给线程池执行,并通过 Future 对象获取异步计算的结果。
使用 Callable 通常结合 FutureTask(实现了 Runnable 和 Future 接口)来包装 Callable 任务,并将其提交给线程池执行,从而可以获得线程执行的结果。

结束线程的工作

上面的代码中结束线程工作的过程中,涉及到了两个API

  • executorService.shutdown()
    相当于关闭线程池,不允许再扔新的线程或者任务进来了。
  • executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
    如果一个线程调用这个方法,那么它就会被阻塞,暂时停止活动直到这个线程池里面的所有线程结束工作,或者等待超过指定时间——这里我们设置了 Long.MAX_VALUETimeUnit.NANOSECONDS,前者是指 无限期等待,后者是指时间单位为 纳秒

这里我们是主线程调用的,所以就是主线程被阻塞.

避免竞态

上述代码中的多线程加法求和用到了 AtomicInteger,它是 java.util.concurrent.atomic 包下原子整数类,顾名思义,它所对应整数上发生的操作都是原子性的,线程只能串行的去累加它,就能避免竞态问题。

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

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

相关文章

文件IO总结

标准C库IO函数和Linux系统IO函数对比 标准c库IO函数 标准C库提供了一系列的输入输出&#xff08;IO&#xff09;函数&#xff0c;这些函数主要包括在 <stdio.h> 头文件中。这些函数可以大致分为几类&#xff1a; 文件操作函数&#xff1a; fopen&#xff1a;打开文件fc…

Linux内核之内核通知文件系统创建的路径:fsnotify_create用法实例(五十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【图解计算机网络】从浏览器地址输入到网页显示的整个过程

从浏览器地址输入到网页显示的整个过程 整体流程DHCPhttp协议报文组装DNSTCP协议封装与TCP三次握手IP协议封装与路由表MAC地址与ARP协议交换机路由器 整体流程 从往浏览器输入一个地址到网页的显示&#xff0c;要经过很长的一个流程&#xff0c;中间涉及到计算机网络的许多知识…

*Linux系统的进程和计划任务管理

目录 一、查看进程 1、程序和进程的关系 *2、ps查看静态进程信息 1&#xff09;ps aux 2&#xff09;ps -elf *3、top查看动态进程信息 4、pgrep查看进程信息 5、pstree查看进程树 二、控制进程 1、进程启动方式 2、进程的前后台调度 3、终止进程的运行 三、计划任…

React【Day4】

路由快速上手 1. 什么是前端路由 一个路径 path 对应一个组件 component 当我们在浏览器中访问一个 path 的时候&#xff0c;path 对应的组件会在页面中进行渲染 2. 创建路由开发环境 # 使用CRA创建项目 npm create-react-app react-router-pro# 安装最新的ReactRouter包 …

Git TortoiseGit 安装使用详细教程

前言 Git 是一个免费的开源分布式版本控制系统&#xff0c;是用来保存工程源代码历史状态的命令行工具&#xff0c;旨在处理从小型到非常大型的项目&#xff0c;速度快、效率高。《请查阅Git详细说明》。TortoiseGit 是 Git 的 Windows Shell 界面工具&#xff0c;基于 Tortoi…

第 2 章:FFmpeg简介

2.1 历史 历史 一些相关术语介绍&#xff1a; 容器&#xff08;Container&#xff09;格式&#xff1a;一种文件封装格式&#xff0c;里边主要包含了流&#xff0c;一般会使用一个特定的后缀名标识&#xff0c;例如.mov、.avi、.wav等。流 &#xff08;Stream&#xff09;&am…

政安晨:【Keras机器学习示例演绎】(五)—— 利用视觉变换器进行物体检测

目录 导言 导入和设置 准备数据集 实施多层感知器&#xff08;MLP&#xff09; 实施补丁创建层 显示输入图像的补丁 实施补丁编码层 构建 ViT 模型 运行实验 评估模型 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与…

第二届 Oceanbase 开发者大会 实录

第二届 Oceanbase 开发者大会 实录 今天很有幸参加了Oceanbase 开发者大会&#xff0c;我是真的我一开始还不知道什么是Oceanbase &#xff0c;直到我开了会才知道。看来真的需要多参加一些这样活动。 会议议程 我们科普一下什么是Oceanbase OceanBase 是阿里巴巴集团推出…

如何进行数据库的迁移与同步——【DBA 从入门到实践】第四期

在日常的数据库运维工作中&#xff0c;我们时常会面临数据库替换、机房搬迁、业务测试以及数据库升级等任务&#xff0c;这些任务都需要对数据进行迁移和同步操作。【DBA 从入门到实践】第4期&#xff0c;将引导大家深入了解数据库迁移的流程&#xff0c;并探讨在迁移过程中可用…

AJAX——图书管理案例

1.渲染列表 自己的图书数据&#xff1a;给自己起个外号&#xff0c;并告诉服务器&#xff0c;默认会有三本书&#xff0c;基于这三本书做数据的增删改查。 // 目标1&#xff1a;渲染图书列表 // 1.1 获取数据 // 1.2 渲染数据const creator 哈哈 // 封装-获取并渲染图书列表函…

《QT实用小工具·二十八》基于qt开发的各种曲线

1、概述 源码放在文章末尾 该项目实现了各种曲线的绘制&#xff0c;下面是项目的demo演示&#xff1a; 项目部分代码如下&#xff1a; #include "frmsmoothcurve.h" #include "ui_frmsmoothcurve.h" #include "smoothcurve.h" #include "…

cocos creator 3.6 发布web手机端 加载进度条添加

cocos creator 升级到3.x之后加载进度条取消了&#xff0c;测试了多个3.x版本最终以creator 3.6.3版本&#xff0c;构建了简单的进度加载 参考链接&#xff1a; https://forum.cocos.org/t/topic/137113 打包web-mobile后&#xff0c;没有进度条。加载的时候只显示一个黑屏。…

【小程序】IOS wx小程序解压获取源文件

根据自己手机的系统&#xff0c;获取wx小程序的缓存目录 一、微信小程序文件存放路径 安卓&#xff1a; /data/data/com.tencent.mm/MicroMsg/{{user哈希值}}/appbrand/pkg/iOS越狱&#xff1a; /User/Containers/Data/Application/{{系统UUID}}/Library/WechatPrivate/{{user…

1.为什么选择Vue框架

参考&#xff1a;百战程序员 为什么选择Vue框架 Vue是什么&#xff1f; 渐进式 JavaScript 框架&#xff0c;易学易用&#xff0c;性能出色&#xff0c;适用场景丰富的 Web 前端框架 为什么要学习Vue Vue是目前前端最火的框架之一Vue是目前企业技术栈中要求的知识点Vue可以…

HarmonyOS 状态管理

在声明式 UI 框架中&#xff0c;数据的改变触发 UI 的重新渲染。在 ArkUI 中不是所有数据的变化都会触发 UI 重新渲染&#xff0c;只有 状态变量 才会引起 UI 重新渲染。 状态变量 状态变量&#xff1a; 指被状态装饰器装饰的变量&#xff0c;只有这种变量的改变才会引起 UI …

【leetcode面试经典150题】63. 删除链表的倒数第 N 个结点(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

软考141-上午题-【软件工程】-杂题+小结

一、杂题 真题1&#xff1a; 真题2&#xff1a; 真题3&#xff1a; 真题4&#xff1a; 真题5&#xff1a; 真题6&#xff1a; 真题7&#xff1a; 真题8&#xff1a; 真题9&#xff1a; 真题10&#xff1a; 真题11&#xff1a; 真题12&#xff1a; 真题13&#xff1a; 真题14&a…

paddlepaddle-gpu安装

背景 之前安装paddlepaddle-gpu遇到各种问题&#xff0c;安装不成功&#xff0c;之前使用了wsldocker的方式&#xff0c;可查看我之前博客&#xff1a;记录paddlepaddle-gpu安装&#xff0c;这要会导致我整个开发流程比较割裂 cuda版本 强烈推荐cuda11.8&#xff0c;paddlep…

SpringBoot项目错误:找不到主类(解决办法)

清理和重新编译项目即可&#xff0c;在项目中点击右键Maven-Reload project&#xff0c;之后再重新运行就行了