有一个 Data 类,它包含并发的 HashMap 和 add() 方法,该方法将元素添加到映射中。 另一个名为 User 类的类包含 updateinfo() ,当触发此方法时,它会调用 Data 类的 add() 方法并传递必要的参数。
在java中
现在,我需要一个侦听器线程,它只在循环中执行两件事。 睡眠 1 秒,然后打印地图的所有元素并将其清空...
但问题是大约 10000 个线程将同时调用 User.updateinfo() 方法,并且没有程序启动的 main 方法,因此如何有效地放置侦听器线程,使其仅调用一次并开始在某个位置运行,并且其余任务正在顺利完成。
==> 在此多线程程序中,侦听器线程只需启动一次。 由于它是后端代码,因此每当用户执行任务 updateinfo() 时都不会调用 main 方法。
由于 10k 线程触发它,我可以放置一个线程池执行器,以便它可以有效地将数据放入 hashmap 中。如果我错了请指导我
如果架构中存在错误,欢迎任何建设性的想法。
提前致谢。
与其同时清空
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 ) ;