【CompletableFuture任务编排】游戏服务器线程模型及其线程之间的交互(以排行榜线程和玩家线程的交互为例子)

需求:

1.我们希望玩家的业务在玩家线程执行,无需回调,因此是多线程处理。

2.匹配线程负责匹配逻辑,是单独一个线程。

3.排行榜线程负责玩家的上榜等。

4.从排行榜线程获取到排行榜列表后,需要给玩家发奖修改玩家数据,因此涉及到排行榜线程和玩家线程的交互。

5.房间线程也希望有多个,这样子各个房间之间业务无交互,进行并行执行。

ThreadManager.java // 负责所有线程的创建

package org.example.testLogicAndRank;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadManager {/*** 逻辑专用线程*/public static ExecutorService[] logicThreadArr;/*** 房间专用线程*/public static ExecutorService[] roomThreadArr;/*** 排行榜专用线程*/public static ExecutorService rankExecutorService = Executors.newSingleThreadExecutor(r -> {Thread t = new Thread(r);t.setName("RankThread");return t;});/*** 匹配专用线程*/public static ExecutorService matchExecutorService = Executors.newSingleThreadExecutor(r -> {Thread t = new Thread(r);t.setName("RankThread");return t;});public static void init() {// 逻辑线程池logicThreadArr = new ExecutorService[Runtime.getRuntime().availableProcessors()];for (int i = 0; i < logicThreadArr.length; i++) {int finalI = i;logicThreadArr[i] = Executors.newSingleThreadExecutor(r -> {Thread t = new Thread(r);t.setName("LogicThread" + finalI);return t;});}// 房间线程池roomThreadArr = new ExecutorService[Runtime.getRuntime().availableProcessors()];for (int i = 0; i < roomThreadArr.length; i++) {int finalI = i;roomThreadArr[i] = Executors.newSingleThreadExecutor(r -> {Thread t = new Thread(r);t.setName("RoomThread" + finalI);return t;});}}
}

LogicThreadManager.java //逻辑线程池

package org.example.testLogicAndRank;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;public class LogicThreadManager {/*** 从其他线程执行一个任务,然后将结果提交到逻辑线程** @param completableFuture* @param consumer* @param <T>*/public static <T> void executeInLogicThread(CompletableFuture<T> completableFuture, Consumer<T> consumer, Object hashObj) {ExecutorService executorService = ThreadManager.logicThreadArr[Math.abs(hashObj.hashCode()) % ThreadManager.logicThreadArr.length];completableFuture.thenAcceptAsync(consumer, executorService);}
}

RankThreadManager.java

package org.example.testLogicAndRank;import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;@Slf4j
public class RankThreadManager {public static CompletableFuture<List<Integer>> getRankList() {return submitInRankThread(() -> {// 查询数据库log.info("查询排行榜");return Lists.newArrayList(1, 2, 3, 4, 5);});}/*** 在排行榜线程执行某个操作,有返回值** @param callable* @param <T>* @return*/public static <T> CompletableFuture<T> submitInRankThread(Callable<T> callable) {return CompletableFuture.supplyAsync(() -> {try {return callable.call();} catch (Exception e) {log.error("", e);}return null;}, ThreadManager.rankExecutorService);}/*** 在排行榜线程执行某个操作,无返回值*/public static void executeInRankThread(Runnable runnable) {ThreadManager.rankExecutorService.submit(runnable);}
}

Main.java

package org.example.testLogicAndRank;import lombok.extern.slf4j.Slf4j;import java.util.List;
import java.util.concurrent.CompletableFuture;@Slf4j
public class Main {public static void main(String[] args) {ThreadManager.init();// 排行榜CompletableFuture<List<Integer>> rankListFuture = RankThreadManager.getRankList();// 假设是给玩家1和2发奖LogicThreadManager.executeInLogicThread(rankListFuture, (rankList) -> {log.info("拿到排行榜数据发奖{}", rankList);}, 1);LogicThreadManager.executeInLogicThread(rankListFuture, (rankList) -> {log.info("拿到排行榜数据发奖{}", rankList);}, 2);}
}/*
17:16:39.314 [RankThread] INFO org.example.testLogicAndRank.RankManager - 查询排行榜
17:16:39.343 [LogicThread2] INFO org.example.testLogicAndRank.Main - 拿到排行榜数据发奖[1, 2, 3, 4, 5]
17:16:39.343 [LogicThread1] INFO org.example.testLogicAndRank.Main - 拿到排行榜数据发奖[1, 2, 3, 4, 5]*/

总结:

可以看出来,我们不再需要什么Promise模式了,有了CompletableFuture后,业务线程的编排和交换数据变得非常容易了!

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

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

相关文章

【GitHub项目推荐--不错的 C 开源项目】【转载】

大学时接触的第一门语言就是 C语言&#xff0c;虽然距 C语言创立已过了40多年&#xff0c;但其经典性和可移植性任然是当今众多高级语言中不可忽视的&#xff0c;想要学好其他的高级语言&#xff0c;最好是先从掌握 C语言入手。 今天老逛盘点 GitHub 上不错的 C语言 开源项目&…

【代码随想录11】239. 滑动窗口最大值 347. 前 K 个高频元素

目录 239. 滑动窗口最大值题目描述做题思路参考代码 347. 前 K 个高频元素题目描述参考代码 239. 滑动窗口最大值 题目描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每…

详解C语言中`||`的短路机制

在C语言中&#xff0c;逻辑或运算符&#xff08;||&#xff09;是一种常用的逻辑运算符&#xff0c;用于组合多个条件表达式。与其他编程语言一样&#xff0c;C语言中的逻辑或运算符具有短路机制&#xff0c;这是一种非常重要的概念&#xff0c;本文将深入解释C语言中的||短路机…

sportplay项目

1.编写userMapping.xml时报错&#xff0c; Error querying database. Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘easyuser’ W…

MSVS C# Matlab的混合编程系列2 - 构建一个复杂(含多个M文件)的动态库:

前言: 本节我们尝试将一个有很多函数和文件的Matlab算法文件集成到C#的项目里面。 本文缩语: MT = Matlab 问题提出: 1 我们有一个比较复杂的Matlab文件: 这个MATLAB的算法,写了很多的算法函数在其他的M文件里面,这样,前面博客的方法就不够用了。会报错: 解决办法如下…

华为机考入门python3--(0)模拟题2-vowel元音字母翻译

分类&#xff1a;字符串 知识点&#xff1a; 字符串转list&#xff0c;每个字符成为list中的一个元素 list(string) 字符串变大小写 str.upper(), str.lower() 题目来自【华为招聘模拟考试】 # If you need to import additional packages or classes, please import …

分享5款简单实用的软件,值得收藏

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.自定义图标——TileIconifier ​ TileIconifier 是一款可以自定义 Windows 开始菜单图标的软件&#…

蓝牙运动耳机什么牌子的好?2024年运动无线耳机推荐

​在选择运动耳机时&#xff0c;我们需要综合考虑音质、舒适度以及适应不同运动场景的能力。好的运动耳机能够提高运动效率&#xff0c;增添锻炼的乐趣。今天&#xff0c;我为大家介绍几款在音质、佩戴舒适度、防水防汗等方面表现卓越的运动耳机&#xff0c;助你选购最适合的一…

《GreenPlum系列》GreenPlum初级教程-05GreenPlum语言DDLDMLDQL

文章目录 第五章 DDL&DML&DQL1.DDL(Data Definition Language)数据定义语言1.1 创建数据库1.2 查询数据库1.3 删除数据库1.4 创建表1.5 修改表1.6 清除表1.7 删除表 2.DML(Data Manipulation Language)数据操作语言2.1 数据导入2.2 数据更新和删除2.3 数据导出 3.DQL(D…

04 单链表

目录 链表的概念和结构单链表OJ练习 1. 链表的概念和结构 1.1 链表的概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 1.从上图可以看出链式结构在逻辑上是连续的&#xff0c;物理上不一定连续 2.现…

139 删除链表中的重复元素II

问题描述&#xff1a;存在一个按照升序排列的链表&#xff0c;给你这个链表的头结点head&#xff0c;请你删除链表中所有存在数字重复情况的节点&#xff0c;只保留链表中没有出现的数字&#xff0c;返回的结果同样按升序的结果链表。 求解思路&#xff1a;双指针求解&#xf…

常用的gpt-4 prompt words收集4

1. it poses a certain risk to my work 这对我来说是一个风险点 2. one point to note is that 需要说的一个问题是 3. What is the English phonetic transcription of ‘emoji’? emoji的音标是什么&#xff1f; 4. it would be best if you can insert some proper …

Docker(十)Docker Compose

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Compose 项目 Docker Compose 是 Docker 官方编排&#xff08;Orchestration&#xff09;项目之一&#xff0c;负责快速的部署分布式…

Vue diff原理

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

NIO和netty的常用类

Netty的NIO的常用概念 ServerBootstrap ServerBootstrap 是一个用于帮助配置和启动服务器的类。它是Netty中用于创建服务器端应用程序的主要入口点 Channel 在计算机网络编程中&#xff0c;Channel&#xff08;通道&#xff09; 是一种抽象概念&#xff0c;代表着数据在源和…

Golang leetcode28 找出字符串中第一个匹配项的下标 KMP算法详解

文章目录 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题暴力求解使用KMP模式匹配算法KMP算法简述 KMP算法的代码实现 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题 暴力求解 func strStr(haystack string, needle string) int { L : len(need…

wayland(wl_shell) + egl + opengles 最简实例

文章目录 前言一、ubuntu 上相关环境准备1. ubuntu 上安装 weston2. 确定ubuntu 上安装的opengles 版本3. 确定安装的 weston 是否支持 wl_shell 接口二、窗口管理器接口 wl_shell 介绍二、代码实例1.egl_wayland_demo.c2. 编译和运行2.1 编译2.2 运行总结参考资料前言 本文主…

UE5 C++学习笔记 FString FName FText相互转换

1.FString 是UE里的String。最接近std::string, 唯一可以修改的字符串类型。性能更低 TEXT(string) TEXT宏&#xff0c;作用是将字符串转换成Unicode&#xff0c;切记UE中使用字符串输出要使用该宏 2. FName 是UE里特有的类型。它更注重于表示名称不区分大小写&#xff0c;不…

基于taro搭建小程序多项目框架,记重点了!!!

前言 为什么需要这样一个框架&#xff0c;以及这个框架带来的好处是什么&#xff1f; 从字面意思上理解&#xff1a;该框架可以用来同时管理多个小程序&#xff0c;并且可以抽离公用组件或业务逻辑供各个小程序使用。当你工作中面临这种同时维护多个小程序的业务场景时&#…

web架构师编辑器内容-完成属性设置的优化

对于业务组件来说&#xff0c;其属性是有很多的&#xff0c;如果把所有属性都平铺在页面上&#xff0c;就会非常长&#xff0c;而且想要更改其中的某些属性&#xff0c;可能需要向下滚动很久才能找到&#xff0c;对于UI的交互不是很友好&#xff0c;需要对属性的不同特性进行分…