最近在看《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\n", 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);
}
}

java 多线程学习笔记(一) -- 计算密集型任务的更多相关文章

  1. Java多线程学习笔记(一)——多线程实现和安全问题

    1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...

  2. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  3. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  4. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  5. Java多线程学习笔记--生产消费者模式

    实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...

  6. java 多线程学习笔记

    这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...

  7. Java 多线程学习笔记:生产者消费者问题

    前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...

  8. java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...

  9. Java多线程学习笔记(一)

    一 概述 一个进程只有一个至少会运行一个线程,Java中同样存在这样,在调用main方法的时候,线程又JVM所创建. package link.summer7c.test; public class ...

随机推荐

  1. Linux配置redis服务器

    1.安装redis 2.开启6379端口,使外部机器能够访问 3.

  2. Redis安装以及基本操作命令

    Redis安装 cd redis-2.6.14make PREFIX=/usr/local/redis install 可能会出现的错误提示>>提示1:make[3]: gcc:命令未找到 ...

  3. log4net初探

    /// <summary> /// Static constructor that initializes logging by reading /// settings from the ...

  4. P2056 采花

    题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成 ...

  5. bzoj 3996 线性代数 —— 最大权闭合子图

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3996 把题中的式子拆开看看,发现就是如下关系: 如果 a[i] == 1 && ...

  6. HDOJ1548(DFS超内存,BFS过了)

    DFS代码 #include<iostream> #include<cstdio> using namespace std; #define Min(a,b) (a<b) ...

  7. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

  8. 关于openstack自动化安装的一点思考

    在openstack针对具体应用的解决方案已成型之后,按照官方文档安装openstack实际上就成了一个繁琐的事情. 我有一个设想,之前实施了一点,还未成功,但是也想记录下来.最终目标:使用U盘直接部 ...

  9. HDFS中hsync方法介绍

    HDFS中hsync方法介绍 原创文章,转载请注明:博客园aprogramer 原文链接:HDFS中hsync方法介绍 1. 背景介绍 HDFS在写数据务必要保证数据的一致性与持久性,从HDFS最初的 ...

  10. 安装mariadb并修改配置文件

    实验环境:CentOS7 #安装mariadb-server包#修改mariadb配置文件/etc/my.cnf.d/server.cnf#添加 skip_name_resolve=ON #不执行将I ...