java框架中如何处理并发和多线程?

Java函数的并发和多线程中的Fork/Join框架如何使用?

Fork/Join 意味着使用分而治之的方法进行竞争。
说白了就是你分工自己做。

本质就是两个东西:RecursiveTask和RecursiveAction。
第一个有结果,第二个没有。

比如你从1 数到1 00,任务被分成小块,小块用叉子丢弃,大块自己数。
加入以获得结果。

创建一个 ForkJoinPool 并将任务转储到其中。
Invoke 同步检索结果,fork+join 异步检索结果。

主要有三种方法:fork 丢弃工作、merge 等待工作、调用丢弃工作本身。

斐波那契数列就是一个很好的例子。
当n很大时,直接递归非常慢。
使用 Fork/Join 可以更快地将任务拆分为小任务并并行执行计算。

小心,如果把任务分成碎片的话,会很慢。
比如n=4 0,如果划分很多小任务,则得不偿失。
右边的任务可以直接计算,左边的任务可以异步执行。

不要向任务添加像 Thread.sleep() 这样的愚蠢操作。
它会减慢整个系统的速度。

Fork/Join 适用于分而治之方法、递归问题和 CPU 工作。
尝试一下吗?

面试官:公司项目中Java的多线程一般用在哪些场景?

说实话,Java项目投入多任务的核心目的就是为了让系统运行得更快,更高效地利用资源,自然提升用户体验。
我在做电商项目的时候深刻体会到了这一点。

以高并发请求处理为例。
例如,如果您访问淘宝或京东,后端服务器无法在处理另一个用户请求之前处理另一个用户请求。
我见过的最糟糕的事情是使用单个线程来处理文件加载器。
当用户下载2 G视频时,整个页面卡住,其他用户只能等待访问。
后来我改用多线程,单独开了一个线程专门用于文件上传。
主线程正在处理其他请求,速度立刻就提升了。
就像陷入高峰时段的交通一样,单车道道路肯定比多车道道路慢。

有趣的是异步工作流程,这一点让我印象特别深刻。
过去,用户注册后,系统必须等到验证邮件发送后才能给予反馈,这让用户感到沮丧。
后来改为圆线来发送电子邮件。
用户注册后,当几秒内提示“邮件已发送”时,体验立刻就不一样了。
我们使用 @Async 注释,并将电子邮件功能放在后台,只需几行代码。

我有一个优化 I/O 密集型操作的具体案例。
我们有一个报告系统,会在每个月的第一天运行所有数据。
我必须等到凌晨 3 点才能参加单线程课程。
后来给每个表的查询分配一个独立的线程,最后发现总耗时从3 4 ms减少到1 2 ms,节省了多线程的等待时间。
当然,这样做的前提是这些查询之间不存在依赖关系。

说到资源隔离,我曾经在解决方案系统中做过一件蠢事——关于解决引用池线程中的逻辑和生成。
导致大促期间,资源请求钱被消耗,连接线程被卡,用户付费出现问题。
然后我很快将其拆分为两个独立的ThreadPoolExecutor,终于完成了。

就涉及的计算任务而言,在项目过程的形象中。
图片的附加功能原本是CPU密集型操作。
单线程处理一张图片需要3 秒。
使用4 根线并联后,数秒内即可得出结果。
Java 8 中使用Stream API创建并行流,使代码量减少了一半,性能大幅提升。

为了访问服务,我们使用ScheduledExecutorService,它比传统的Timer可靠得多。
每天下午3 点有一次数据同步工作。
这是通过 Scheduled Executor Service 完成的,这比使用 Timer 更不烦人。

最后,做一个关于分布式计算的报告。
我们对大型 MGE 使用 Spark。
执行器进程机制的倍增实际上增加了集群的吞吐量。
然而,我在这方面没有太多经验。
我特别遵循最好的团队计划。

但说实话,多阶段并不是万能的。
在我的一个项目中,要将某个View I/O操作改为并行,改变顺序的成本比等待I/O的成本更大,所以我不得不改变它。
因此,在进入多任务处理之前,最好对作品的第一个角色进行评估。

就顺序安全而言,ConcurrentHashMap实际上比HashMap更容易使用。
在我们的选择中随处使用它。
但这件事非常令人不安。
最糟糕的看法是两个线程持有彼此需要的锁,最后只能关闭服务。
所以在设计锁机制的时候,需要画一个定时器,看看是否存在等待循环。

总的来说,多元的核心价值Java的特点在于异步和并行,但是要看情况。
在 I/O 密集型场景和分布式系统中效果最为明显。
但也许变成了“为了乘法而乘法”,这实际上会阻碍事情的发展。