zoukankan      html  css  js  c++  java
  • java 多线程学习笔记(一) -- 计算密集型任务

    最近在看《Java虚拟机并发编程》,在此记录一些重要的东东。

    线程数的确定:
    1. 获取系统可用的处理器核心数:int numOfCores = Runtime.getRuntime().availableProcessors()
    2. 如果任务是计算密集型的,则线程数 = numOfCores
            如果任务是IO密集型的,则线程数 = numOfCores / (1 - 阻塞系数), 其中阻塞系数在0~1之间。
    注:如果任务被阻塞的时间大于执行时间, 则这些任务是IO密集型的,我们就需要创建比处理器核心数大几倍数量的线程


    在解决问题的过程中使处理器一直保持忙碌状态比将负载均摊到每个子任务要实惠得多。
    任务完成并不代表线程消亡。

    计算密集型任务:如求1到10000000内所有素数的个数

    1. AbstractPrimeFinder

    public abstract class AbstractPrimeFinder {
    
        public boolean isPrime(final int number){
            if(number <= 1) return false;
            
            for(int i = 2; i <=Math.sqrt(number); i++){
                if (number % i == 0) 
                    return false;
            }
            return true;
        }
        
        public int countPrimesInRange(final int lower, final int upper){
            int total = 0;
            for( int i = lower; i <= upper; i++){
                if(isPrime(i))
                    total++;
            }
            return total;
        }
        
        public void timeAndComputer(final int number){
            long start = System.nanoTime();
            int numberOfPrimes = countPrimes(number);
            long end = System.nanoTime();
            
            System.out.printf("Number of primes under %d is %d
    ", number, numberOfPrimes);
            System.out.println("Spend time(seconds) is " + (end-start)/1.0e9);
        }
        
        public abstract int countPrimes(final int number);
    }

    2. ConcurrentPrimeFinder

    /**
     * 对于计算密集型的任务,增加线程数并没有什么意义,线程数应该等于CPU内核数。如果较难把任务均摊到CPU,则
     * 可以把任务切分成较多块,以确保CPU完成某块任务后,可以继续处理其它块。防止某个CPU完成任务后处于空闲状态。
     * @author shj
     *
     */
    public class ConcurrentPrimeFinder extends AbstractPrimeFinder{
        private final int poolSize;
        private final int numberOfParts;
        
        public ConcurrentPrimeFinder(int poolSize, int numberOfParts){
            this.poolSize = poolSize;
            this.numberOfParts = numberOfParts;
        }
    
        @Override
        public int countPrimes(final int number) {
            int count = 0 ;
            try{
                List<Callable<Integer>> partitions = new ArrayList<>();
                int chunksPerPartition = number / numberOfParts;
                for(int i = 0; i < numberOfParts; i++){
                    final int lower = (i * chunksPerPartition) + 1;
                    final int upper = (i == numberOfParts - 1) ? number : lower + chunksPerPartition - 1;
                    partitions.add(new Callable<Integer>(){
                        public Integer call(){
                            return countPrimesInRange(lower, upper);
                        }
                    });
                }
                
                ExecutorService executorPool = Executors.newFixedThreadPool(poolSize);
                List<Future<Integer>> results = executorPool.invokeAll(partitions, 10000, TimeUnit.SECONDS);
                executorPool.shutdown();
                
                for(Future<Integer> result : results){
                    count += result.get();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            return count;
        }
    
        public static void main(String[] args){
            int cores = Runtime.getRuntime().availableProcessors();
            int numberOfParts = 20; //划分成子区间的数量, 修改此值查看运行时间的变化
            new ConcurrentPrimeFinder(cores,numberOfParts).timeAndComputer(10_000_000);
        }
    }
  • 相关阅读:
    mysql报错解决
    数据存储
    记录python接口自动化测试--把操作excel文件的方法封装起来(第五目)
    基础补充:使用xlrd模块读取excel文件
    记录python接口自动化测试--利用unittest生成测试报告(第四目)
    记录python接口自动化测试--pycharm执行测试用例时需要使用的姿势(解决if __name__ == "__main__":里面的程序不生效的问题)(第三目)
    记录python接口自动化测试--unittest框架基本应用(第二目)
    记录python接口自动化测试--requests使用和基本方法封装(第一目)
    连接数据后,当执行查询语句报错:ORA-01219: 数据库未打开: 仅允许在固定表/视图中查询
    通过运行一个tomcat容器来记录下初学docker常用的几个命令---容器篇
  • 原文地址:https://www.cnblogs.com/langfanyun/p/6166114.html
Copyright © 2011-2022 走看看