Java线程之ExecutorService.invokeAny()

本文介绍了如何使用Java线程的ExecutorService.invokeAny()方法来实现多线程并行计算。该方法适用于启动多个线程执行独立任务,一旦有一个线程完成任务并获取结果,它会立即停止所有其他线程。文中通过一个趣味性的例子,即搜索硬盘中特定文件的场景,来解释invokeAny()的实用价值。示例代码展示了如何创建任务列表并调用invokeAny()获取首个结果,从而提高程序效率。
摘要由CSDN通过智能技术生成

有一类多线程编程模式是这样的:启动多个线程,相互独立的(无同步)去计算一个结果,当某一个线程得到结果之后,立刻终止所有线程,因为只需要一个结果就够了。

实际应用场景:作为男生,电脑上必须有苍老师的爱情动作片。这种片子必须藏得非常隐蔽,隐蔽到什么程度呢?自己都忘了把它藏哪里了,这可咋办啊?编写多线程程序,针对每一个硬盘分区,启动一个线程,搜索该硬盘分区上的所有文件,找名字中含有“苍老师”的文件。由于这些片子都是集中存放,因此,我只需要找到一个,就无需在继续寻找。例如,某线程在D盘找到了一个苍老师的文件,则此线程立刻终结,同时,处理C盘,E盘的线程也应该立刻终结,因为既然D盘找到了,其他盘搜索就毫无意义了,肯定没有结果。


ExecutorService.invokeAny()就是为此设计的,他接收的参数是一个List,List中的每一个元素必须实现Callable接口。他的功能是依此启动新的线程执行List中的任务,并将第一个得到的结果作为返回值,然后立刻终结所有的线程。其用法如下:

String s =  es.invokeAny(list)

具体的代码如下:

public class ThreadLocalTest {

	public static void main(String[] args) {
		ExecutorService es = Executors.newFixedThreadPool(10);
		List<Callable<String>> l
JavaExecutorService是一个线程池,可以用来执行任务。遍历ExecutorService的过程就是遍历线程的所有线程。 遍历ExecutorService方法有两种: 1. 使用ExecutorService方法 可以使用ExecutorService方法来获取线程的所有线程。其ExecutorService方法包括:submit、execute、invokeAll、invokeAny等方法,这些方法会返回一个Future对象,可以使用这个对象来获取线程的状态。 2. 使用Java的反射机制 通过Java的反射机制,可以获取ExecutorService的私有变量和方法,从而遍历线程的所有线程。 下面是使用ExecutorService方法遍历线程池的示例代码: ```java ExecutorService executorService = Executors.newFixedThreadPool(10); List<Future<?>> futures = executorService.invokeAll(tasks); for (Future<?> future : futures) { while (!future.isDone()) { Thread.sleep(100); } } executorService.shutdown(); ``` 在这个示例代码,我们创建了一个固定大小为10的线程池,然后使用invokeAll方法提交了一些任务,得到了一个Future的列表。接下来,我们遍历这个列表,等待每个任务完成。最后,我们使用shutdown方法关闭线程池。 下面是使用反射机制遍历线程池的示例代码: ```java ExecutorService executorService = Executors.newFixedThreadPool(10); Field workersField = ThreadPoolExecutor.class.getDeclaredField("workers"); workersField.setAccessible(true); List<?> workers = (List<?>)workersField.get(executorService); for (Object worker : workers) { Field threadField = worker.getClass().getDeclaredField("thread"); threadField.setAccessible(true); Thread thread = (Thread)threadField.get(worker); System.out.println(thread.getName()); } executorService.shutdown(); ``` 在这个示例代码,我们使用反射机制获取了ThreadPoolExecutor的私有变量“workers”,这个变量是一个存储所有工作线程的列表。接下来,我们遍历这个列表,获取每个工作线程的Thread对象,然后打印出线程的名称。最后,我们使用shutdown方法关闭线程池。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值