码迷,mamicode.com
首页 > 编程语言 > 详细

Java并发编程初探

时间:2015-03-15 07:05:13      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

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();

 

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

Java并发编程初探

标签:

原文地址:http://www.cnblogs.com/color-my-life/p/4338729.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!