zoukankan      html  css  js  c++  java
  • Java并发编程初探

    package test;
    
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    public class Test {
        public static void getJavaFile(String currentpath,List<File> files){
            File dir = new File(currentpath);
            if(dir.exists()){
                File temp[] = dir.listFiles();
                if(temp != null)
                {            
                    for (File b: temp) {
                        if (b.isFile() && b.toString().endsWith(".java")) {
                            files.add(b);
                        }
                        else if(b.isDirectory()){
                            getJavaFile(b.toString(), files);
                        }
                    }
                }
            }
        }
        public final static float percent = (float) 0.9;
        public final static int poolsize = (int) (Runtime.getRuntime().availableProcessors()/(1-percent));
        public static void main(String[] args) throws Exception{
            // TODO Auto-generated method stub
            //初始化文件集合
            String path = "G:"+File.separator+"src";
            List<File> fs = new ArrayList<>();
            getJavaFile(path, fs);
            
            //顺序执行
            long start = System.currentTimeMillis();
            int total = 0;
            for(File s : fs){
                int i = getCount(s);
                //System.out.println(s.getName()+"长度为:"+i);
                total+=i;
            }
            long end = System.currentTimeMillis();
            System.out.println("顺序执行的时间:"+(end-start)+"得出来的结果:"+total);
            
            
            
            final ExecutorService executorpool = Executors.newFixedThreadPool(poolsize);
            final List<Callable<Integer>> partitions = new ArrayList<>();
            for(final File f1 : fs){
                partitions.add(new Callable<Integer>() {
    
                    @Override
                    public Integer call() throws Exception {
                        // TODO Auto-generated method stub
                        Integer i = getCount(f1);
                        //System.out.println(f1.getName()+"长度为:"+i);
                        return i;
                    }
                });
            }
            long startbingfa = System.currentTimeMillis();
            final List<Future<Integer>> nums = executorpool.invokeAll(partitions,5,TimeUnit.MINUTES);
            int totalbingfa = 0;
            for(final Future<Integer>i : nums){
                    totalbingfa = totalbingfa+i.get();
            }
            executorpool.shutdown();
            long endbingfa = System.currentTimeMillis();
            System.out.println("并发的时间:"+(endbingfa-startbingfa)+"得出来的结果:"+totalbingfa);
    
        }
        
        public static int getCount(File f) throws IOException{
            int count = 0;
            Reader br = new FileReader(f);
            //String line = "";
            int c;
            while ((c = br.read()) != -1) {
                if('a' == (char)c){
                    count++;
                }
            }
            return count;
        }
    }

    上面可以看到,我设置了大量的文件,然后使用并发和顺序执行,执行结果如下:

    顺序执行的时间:140得出来的结果:14002
    并发的时间:86得出来的结果:14002
    可以看到,其实改进并不特别明显,究其原因就是,代码中的任务的IO密集型特征并不明显,但是就这个而言,时间仍然是有所改进的,采用的是线程池方式,首先定义一个任务集合partitions,

    final List<Callable<Integer>> partitions = new ArrayList<>();

    其中Integer表示的是任务的返回类型

    然后给任务集定义任务,比如上面的就是一个读取文件并且返回一个Integer类型的数据.

    然后定义任务服务

    final ExecutorService executorpool =Executors.newFixedThreadPool(poolsize);

    这里设置的是线程池的大小,也就是能够同时运行的任务数.

    然后开始执行

    final List<Future<Integer>> nums = executorpool.invokeAll(partitions,5,TimeUnit.MINUTES);

    这里返回的是任务集合的全体的返回结果,然后我们遍历nums,用get方法去得到单个结果.

    最后要关闭线程池

    executorpool.shutdown();

    线程池的大小并不是设置的越大越好,根据具体的环境而来,

  • 相关阅读:
    常用git指令操作
    eclipse中常用快捷键整理
    Java Dom解析xml文件
    Spring IOC的注入方式
    Spring framework bean的作用域,生命周期
    android中的bundle使用
    python ftplib模块
    python requests用法总结
    限制字符串 剔除费需要字符然后将多余空格删除
    MFC Edit Control 编辑控件 属性和API
  • 原文地址:https://www.cnblogs.com/color-my-life/p/4338729.html
Copyright © 2011-2022 走看看