executor-关于线程池中get()的疑问

问题描述

关于线程池中get()的疑问

如果我的文件夹下共有五个空文件,2个txt文档,那么会产生6个线程,但是为什么在下面代码中count只出现了5次?每个线程都会运行到这段代码的啊。

    for (Future<Integer> futureItem : results) {
                count += futureItem.get();
                        System.out.println("count出现了一次");
            }

运行结果如下:

代码如下:

 public class ThreadPoolTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner sc = new Scanner(System.in);
        System.out.println("please enter the starting file:");
        String fileName = sc.nextLine();
        System.out.println("please enter what you wang to find:");
        String keybroad = sc.nextLine();

        File file = new File(fileName);
        ExecutorService pool = Executors.newCachedThreadPool();
        MathCounter mathCounter = new MathCounter(file, keybroad,pool);
        Future<Integer> future = pool.submit(mathCounter);
        try {
            System.out.println("包含关键字的文件的个数:"+ future.get());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

       class MathCounter implements Callable<Integer>{

        File file;
        String keybroad;
        ExecutorService pool;
        List<Future<Integer>> results = new ArrayList<>();

        public MathCounter(File file, String keybroad, ExecutorService pool) {
            // TODO Auto-generated constructor stub
            this.file = file;
            this.keybroad = keybroad;
            this.pool = pool;
        }

        @Override
            public Integer call() throws Exception {
            // TODO Auto-generated method stub
            int count=0;
            File[] files = file.listFiles();
            String string;
            for (File file_search : files) {
                if (file_search.isDirectory()) {
                    MathCounter mathCounter = new MathCounter(file_search, keybroad,pool);
                    Future<Integer> future = pool.submit(mathCounter);
                    results.add(future);
                }else {
                    if (file_search.canRead()) {
                        boolean flag = false;
                        int numberLine = 0;
                        Scanner scanner = new Scanner(file_search);
                        while(scanner.hasNextLine()){
                            numberLine++;
                            string = scanner.nextLine();
                            if (string.contains(keybroad)) {
                                flag = true;
                                System.out.printf("%s: %d, %s
", file_search.getName(), numberLine, string);
                            }
                        }
                        if (flag == true) {
                            count++;
                        }
                    }
                }//else
            }

            for (Future<Integer> futureItem : results) {
                count += futureItem.get();
                        System.out.println("count出现了一次");
            }

            return count;
        }

    }

解决方案

$.get(url)的疑问

解决方案二:

关于这个多线程的问题,你可以参考这篇文章深入理解线程与进程的概念

时间: 2024-08-03 10:31:23

executor-关于线程池中get()的疑问的相关文章

java 线程池中如何自定义每个线程名称

问题描述 java 线程池中如何自定义每个线程名称 **java 线程池中如何自定义每个线程名称 java 线程池中如何自定义每个线程名称 ** 解决方案 补充下,线程池的创建线程池对象时,有一个参数是ThreadFactory类型,如果不传递,默认用的是DefaultFactory,我们可以自定义一个ThreadFactory然后作为参数传到进去,这个类里面就可以自定义线程池中创建的线程的名称.api: public ThreadPoolExecutor(int corePoolSize,in

《C#多线程编程实战(原书第2版)》——3.6 在线程池中使用等待事件处理器及超时

3.6 在线程池中使用等待事件处理器及超时 本节将描述如何在线程池中对操作实现超时,以及如何在线程池中正确地等待. 3.6.1 准备工作 为了学习本节,你需要安装Visual Studio 2015.除此之外无需其他准备.本节的源代码放置在BookSamples\Chapter3\Recipe5目录中. 3.6.2 实现方式 请执行以下步骤来了解在线程池中实现超时及正确的等待: 1.启动Visual Studio 2015.新建一个C#控制台应用程序项目. 2.在Program.cs文件中加入以

《C#多线程编程实战(原书第2版)》——3.2 在线程池中调用委托

3.2 在线程池中调用委托 本节将展示在线程池中如何异步的执行委托.另外,我们将讨论一个叫做异步编程模型(Asynchronous Programming Model,简称APM)的方式,这是.NET历史中第一个异步编程模式. 3.2.1 准备工作 为了学习本节,你需要安装Visual Studio 2015.除此之外无需其他准备.本节的源代码放置在BookSamples\Chapter3\Recipe1目录中. 3.2.2 实现方式 请执行以下步骤来了解如何在线程池中调用委托: 1.启动Vis

戏(细)说Executor框架线程池任务执行全过程(下)

原文链接:   首发表于infoq.com 2015年6月 上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现ThreadPoolExecutor来分析接收任务的主要逻辑,发现ThreadPoolExecutor的工作思路和我们带项目的老大的工作思路完全一致.在本文中我们将继续后面的步骤,着重描述下任务执行的过程和任务执行结果获取的过程.会很容易发现,

戏(细)说Executor框架线程池任务执行全过程(上)

原文链接   归档下发表于infoq.com 2015年6月的两篇文章. 内容综述 基于Executor接口中将任务提交和任务执行解耦的设计,ExecutorService和其各种功能强大的实现类提供了非常简便方式来提交任务并获取任务执行结果,封装了任务执行的全部过程.本文尝试通过对j.u.c.下该部分源码的解析以ThreadPoolExecutor为例来追踪任务提交.执行.获取执行结果的整个过程.为了避免陷入枯燥的源码解释,将该过程和过程中涉及的角色与我们工作中的场景和场景中涉及的角色进行映射

如何等待java线程池中所有任务完成

一.等待线程池所有线程完成: 有时候我们需要等待java thread pool中所有任务完成后再做某些操作,如想要等待所有任务完成,仅需调用threadPool.awaitTermination()方法即可,请查看如下代码: ExecutorService threadPool = Executors.newFixedThreadPool(ConfigUtil.ACCESSDB_THREAD_POOL_SIZE); for(String key:noneExsitKeys){ Concurre

如何结束线程池中的线程.

问题描述 我创建了一个线程调用scheduleAtFixedRate()方法Executors.newScheduledThreadPool(1).scheduleAtFixedRate(newRunnable(),1,1,TimeUnit.SECONDS);如果把它结束掉? 解决方案 解决方案二:每个线程都有ID标示遍历线程池找到对应线程把它destroy了

从源代码分析Universal-Image-Loader中的线程池

一般来讲一个网络访问就需要App创建一个线程来执行,但是这也导致了当网络访问比较多的情况下,线程的数目可能积聚增多,虽然Android系统理论上说可以创建无数个线程,但是某一时间段,线程数的急剧增加可能导致系统OOM.在UIL中引入了线程池这种技术来管理线程.合理利用线程池能够带来三个好处.第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗.第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行.第三:提高线程的可管理性.线程是稀缺资源,如果无限制的创建,

java开发中几种常见的线程池

线程池 java.util.concurrent:Class Executors 常用线程池 几种常用的的生成线程池的方法: newCachedThreadPool newFixedThreadPool newScheduledThreadPool newSingleThreadExecutor newSingleThreadScheduledExecutor 例子:newFixedThreadPool ExecutorService threadPool = Executors.newFixe