Java 并发编程(六)-Fork/Join异步回调

news2024/11/23 21:43:04

一、并发编程

1、Fork/Join分支合并框架

    Fork/Join它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。Fork/Join框架要完成两件事情:

    Fork:把一个复杂任务进行分拆,大事化小

    Join:把分拆任务的结果进行合并

RecursiveTask 递归任务:继承后可以实现递归(自己调自己)调用的任务。
@since 1.7

public abstract class RecursiveTask<V> extends ForkJoinTask<V>

RecursiveTask构造方法:
1.RecursiveTask()

RecursiveTask方法:
1.protected abstract V compute():此任务执行的主要计算。
2.protected boolean exec():实现递归任务的执行约定。
3.V getRawResult():返回ForkJoinTask将返回的结果。join(),即使此任务异常完成,
或者如果未知此任务已完成,则为null。
4.protected void setRawResult(V value):强制返回给定的值作为结果。

-----------------------------------------------------------------------
ForkJoinTask<V>
@since 1.7

public abstract class ForkJoinTask<V> extends Object 
implements Future<V>, Serializable

ForkJoinTask<V>构造方法:
1.ForkJoinTask()

ForkJoinTask<V>常用方法:
1.ForkJoinTask<V> fork():安排异步执行此任务。
2.V get():如有必要,等待计算完成,然后检索其结果。
3.V join():完成计算后返回计算结果。

-----------------------------------------------------------------------
ForkJoinPool

public class ForkJoinPool extends AbstractExecutorService

ForkJoinPool构造方法:
1.ForkJoinPool()

ForkJoinPool常用方法:
1.void execute(ForkJoinTask<?> task):安排(异步)执行给定任务。
2.void execute(Runnable task):在将来的某个时间执行给定的命令。
3.<T> ForkJoinTask<T> submit(Callable<T> task):提交一个返回值的任务以供执行,
并返回一个表示任务挂起结果的未来。
4.<T> ForkJoinTask<T> submit(ForkJoinTask<T> task):提交要执行的ForkJoinTask。
5.ForkJoinTask<?> submit(Runnable task):提交可运行任务以执行,并返回表示该任务的未来。
6.<T> ForkJoinTask<T> submit(Runnable task, T result):提交可运行任务以执行,
并返回表示该任务的未来。
7.void shutdown():启动有序关机,执行以前提交的任务,但不接受新任务。

 Fork/Join示例:

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

//求1+2+3+....100。需要拆分任务不超过10个数进行相加拆分
public class ForkJoinDemo {

	public static void main(String[] args) throws Exception {
		MyTask myTask = new MyTask(0,100);
		//创建分支合并池对象
		ForkJoinPool forkJoinPool = new ForkJoinPool();
		ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);
		//获取最终合并之后结果
		Integer result = forkJoinTask.get();
		System.out.println(result);
		//关闭池对象
		forkJoinPool.shutdown();
	}
}

@SuppressWarnings("serial")
class MyTask extends RecursiveTask<Integer>{

	private static final Integer VALUE = 10;
	private int begin;
	private int end;
	private int result;
	
	public MyTask(int begin, int end) {
		this.begin = begin;
		this.end = end;
	}

	@Override
	protected Integer compute() {
		//判断
		if ((end-begin) <= VALUE) {
			for (int i = begin; i <= end; i++) {
				result = result + i;
			}
		}else {
			int middle = (begin+end)/2;
			//拆分左边
			MyTask task01 = new MyTask(begin, middle);
			//拆分右边
			MyTask task02 = new MyTask(middle+1, end);
			//调用方法拆分
			task01.fork();
			task02.fork();
			//合并结果
			result = task01.join() +task02.join();
		}
		return result;
	}
}

2、CompletableFuture异步回调

同步:

异步:

CompletableFuture异步回调示例:

import java.util.concurrent.CompletableFuture;

public class CompletableFutureDemo {

	public static void main(String[] args) throws Exception {
		
		//同步调用
		CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(()->{
			System.out.println(Thread.currentThread().getName() + " :completableFuture1");
		});
		completableFuture1.get();
		
		//异步调用
		CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(()->{
			System.out.println(Thread.currentThread().getName() + " :completableFuture2");
			return 1024;
		});
		completableFuture2.whenComplete((t,u)->{
			System.out.println("--t--"+t);//t:表示成功的返回值
			System.out.println("--u--"+u);//u:表示失败异常的信息
		}).get();
		
		//异步调用
		CompletableFuture<Integer> completableFuture3 = CompletableFuture.supplyAsync(()->{
			System.out.println(Thread.currentThread().getName() + " :completableFuture3");
			//模拟异常
			int i = 10/0;
			return 1024;
		});
		completableFuture3.whenComplete((t,u)->{
			System.out.println("--t--"+t);//t:表示成功的返回值
			System.out.println("--u--"+u);//u:表示失败异常的信息
		}).get();
		
	}
}

实际开发中一般不会用CompletableFuture异步回调。都会使用MQ消息队列的方式。

Java 并发编程(五)-线程池

每天⽤⼼记录⼀点点。内容也许不重要,但习惯很重要!
一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

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

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

相关文章

嵌入式系统基础

嵌入式系统学习的3条路线 路线差别 单片机入门&#xff08;HAL&#xff09; 简单、快速&#xff0c;实际上工作中涉及单片机编程时&#xff0c;也提倡使用HAL库。对于学习来说&#xff0c;HAL库封装了很多技术细节&#xff0c;对技术成长帮助不大。 比如&#xff0c;可能接触…

前后端开发鄙视链的真相,希望对从事前后端开发的小伙伴有些帮助

一、常规的工资对比 前后端的工资情况怎么样?过来人可以负责任的告诉大家:据我所知,至少在杭的网易、阿里,前端跟后端是一个批发价。

探索泰勒级数在机器学习中的作用:从函数逼近到模型优化

一、介绍 泰勒级数是数学中的一个基本概念&#xff0c;在机器学习领域有着重要的应用。本文将探讨泰勒级数的基础知识、它在机器学习中的相关性以及一些具体应用。 揭开复杂性&#xff1a;利用泰勒级数增强机器学习应用的理解和效率。 二、理解泰勒级数 在数学中&#xff0c;泰…

excel手撕神经网络(只需高中数学基础)

神经网络最基础部分是由神经元组成&#xff0c;一个神经元相当于是一个一次函数&#xff0c;yaxb 即在已知x&#xff0c;和y情况下&#xff0c;怎么使用神经网络求解a和b 如下是使用excel求解的神经网络&#xff0c;可以方便理解神经网络运行原理 excel玩具神经网络下载地址 百…

swing快速入门(十五)

注释很详细&#xff0c;直接上代码 上一篇 新增内容 1.文件对话框&#xff08;保存文件&#xff09; 2.文件对话框&#xff08;打开文件&#xff09; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class swing_tes…

软实力篇---第五篇

系列文章目录 文章目录 系列文章目录前言一、HR 最喜欢问程序员的 20 个问题二、面试中的礼仪与举止前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、HR 最喜欢…

tomcat启动异常:子容器启动失败(a child container failed during start)

最近在使用eclipse启动Tomcat时&#xff0c;发现一个问题&#xff0c;启动以前的项目突然报子容器启动异常。 异常信息如下&#xff1a; 严重: 子容器启动失败 java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: 无法启动组件[org.apache.…

运维对数据库的一些要求(安装,部署,权限,mysqldump,xtrabackup的备份和还原)

目录 一、安装部署二、数据库的权限分配1.密码策略2.MySQL中授权(grant)和撤销授权(revoke&#xff09; 三、数据库的备份还原1、mysqldump备份数据库2、Percona XtraBackup备份数据库1、Percona XtraBackup的介绍2、Percona XtraBackup安装3、Percona XtraBackup8.0的使用1.全…

低代码是什么?可能取代人工吗?

低代码开发是近年来迅速崛起的软件开发方法&#xff0c;让编写应用程序变得更快、更简单。有人说它是美味的膳食&#xff0c;让开发过程高效而满足&#xff0c;但也有人质疑它是垃圾食品&#xff0c;缺乏定制性与深度。你认为低代码到底是美味的膳食还是垃圾食品呢&#xff0c;…

PyCharm控制台异常堆栈乱码问题解决

目录 1、问题描述2、问题原因3、问题解决 1、问题描述 PyCharm环境都已经配置成了UTF-8编码&#xff0c;控制台打印中文也不会出现乱码&#xff0c;但异常堆栈信息中如果有中文会出现中文乱码&#xff1a; 这种该怎么解决呢&#xff1f; 2、问题原因 未将PyCharm编码环境与项目…

如何使用ycsb工具对mongodb进行性能测试过程

测试环境&#xff1a; linux系统&#xff1a;Centos 7.2 ,版本&#xff1a;Red Hat 4.8.5-44) YCSB简介 ycsb是一款性能测试工具&#xff0c;用Java写的&#xff0c;并且什么都可以压&#xff0c;像是mongodb&#xff0c;redis&#xff0c;mysql&#xff0c;hbase&#xff0c;等…

Leetcode的AC指南 —— 链表:19.删除链表的倒数第N个节点

摘要&#xff1a; Leetcode的AC指南 —— 链表&#xff1a;19.删除链表的倒数第N个节点。题目介绍&#xff1a;给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 文章目录 一、题目二、解析1、滑动窗口/快慢指针&#xff08;傻傻分不清&…

探索灵活性与可维护性的利器:策略(Strategy)模式详解

目录 ​编辑 1. 策略模式概述&#xff1a; 2. 主要角色&#xff1a; 3. 实例场景&#xff1a; 4. 具体实现步骤&#xff1a; 步骤一&#xff1a;定义策略接口 5. 使用策略模式的客户端代码&#xff1a; 总结&#xff1a; 我的其他博客 1. 策略模式概述&#xff1a; 策…

【Jmeter】Jmeter基础6-Jmeter元件介绍之前置处理器

前置处理器主要用于处理请求前的准备工作&#xff0c;如&#xff1a;参数、环境变量的设置等。 2.6.1、JSR223预处理程序 作用&#xff1a;请求前的准备工作。 参数说明&#xff1a; 语言&#xff1a;开发脚本所使用的语言&#xff0c;可通过下拉列表选择。参数&#xff1a;传…

Vue3快速上手笔记

Vue3快速上手 1.Vue3简介 2020年9月18日&#xff0c;Vue.js发布3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;海贼王&#xff09;耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址&#xff1a;https://github.com/vuejs/vue-next/release…

DC-2靶场

DC-2 下载地址&#xff1a;DC and Five86 Series Challenges - Downloads​编辑https://www.five86.com/downloads.html DC-2环境配置&#xff1a;解压后在vm虚拟机点击左上方文件-->打开-->选择解压后的DC-2。把kali和DC-2的网路适配器都改成NAT模式 flag1 首先进行主…

vue-element-admin如何把mock换成使用真实后台接口

1&#xff09;修改vue.config.js文件 use strict const path require(path) const defaultSettings require(./src/settings.js)function resolve(dir) {return path.join(__dirname, dir) }const name defaultSettings.title || vue Element Admin // page title// If you…

数据结构面试题和题目解析

以下是一些数据结构的面试题和解析&#xff1a; 1. 什么是链表&#xff1f; 链表是一种线性数据结构&#xff0c;由一系列节点组成&#xff0c;每个节点包含数据部分和指向下一个节点的指针。链表的主要优点是插入和删除操作比较方便&#xff0c;但访问链表中的元素不如访问数组…

Windows7下双网卡绑定(双网络冗余)

1.首先需要电脑主机里至少有两张网卡。 2.打开计算机管理&#xff0c;点击左侧的设备管理器&#xff1a; 3.点击展开右侧的 网络适配器&#xff1a; 4.如下是我们即将需要进行绑定的两张网卡&#xff1a; 5.右键点击第一张网卡&#xff0c;选择属性&#xff1a; 6.选择 分组 栏…

Angular中使用Intersection Observer API实现无限滚动

背景&#xff1a; 实现原理为 在data下面加一个loading元素 如果此元素进入视窗 则调用api获取新的数据加到原来的数据里面&#xff0c;这时loading就会被新数据顶下去&#xff0c;如此循环。 <div id"dataContainer"></div> <div id"loadingCo…