如何在多线程程序中仅启动一次监听器线程

问题描述 投票:0回答:1

有一个 Data 类,它包含并发的 HashMap 和 add() 方法,该方法将元素添加到映射中。 另一个名为 User 类的类包含 updateinfo() ,当触发此方法时,它会调用 Data 类的 add() 方法并传递必要的参数。

在java中

现在,我需要一个侦听器线程,它只在循环中执行两件事。 睡眠 1 秒,然后打印地图的所有元素并将其清空...

但问题是大约 10000 个线程将同时调用 User.updateinfo() 方法,并且没有程序启动的 main 方法,因此如何有效地放置侦听器线程,使其仅调用一次并开始在某个位置运行,并且其余任务正在顺利完成。

==> 在此多线程程序中,侦听器线程只需启动一次。 由于它是后端代码,因此每当用户执行任务 updateinfo() 时都不会调用 main 方法。

由于 10k 线程触发它,我可以放置一个线程池执行器,以便它可以有效地将数据放入 hashmap 中。如果我错了请指导我

如果架构中存在错误,欢迎任何建设性的想法。

提前致谢。

java multithreading concurrency backend threadpoolexecutor
1个回答
0
投票

与其同时清空

Map
,不如直接替换它。保留一个指向最新地图对象的
AtomicReference
实例。

final AtomicReference < ConcurrentMap < UUID , Instant > > mapRef = new AtomicReference<>( new ConcurrentHashMap < UUID , Instant > ()  ) ;

一万个平台线程可能不切实际。如果合适,请考虑在 Java 21+ 中使用虚拟线程。或者重构以向执行器服务提交一万个任务。

您的地图的代码探测值将执行以下操作:

mapRef.get().put( UUID.randomUUID() , Instant.now() ) ;

转储地图内容的家务活将是在

Runnable
(或 Jakarta EE 服务器中的托管等效项)中重复运行的
Callable
/
ScheduledExecutorService
。该任务将简单地取代地图。

ConcurrentMap < UUID , Instant > newMap = new ConcurrentHashMap < UUID , Instant > () ;
ConcurrentMap < UUID , Instant > oldMap = mapRef.getAndSet( newMap ) ;
System.out.println( oldMap ) ;
© www.soinside.com 2019 - 2024. All rights reserved.