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\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 多线程学习笔记(一) -- 计算密集型任务的更多相关文章
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java 多线程学习笔记:生产者消费者问题
前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...
- java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...
- Java多线程学习笔记(一)
一 概述 一个进程只有一个至少会运行一个线程,Java中同样存在这样,在调用main方法的时候,线程又JVM所创建. package link.summer7c.test; public class ...
随机推荐
- Hibernate学习---第十四节:hibernate之session线程安全
1.hibernate.cfg.xml 文件中添加如下代码开启线程安全: <property name="hibernate.current_session_context_class ...
- Python习题-一个函数实现读写功能
def new_op_file(filename,content=None): f = open(filename,'a+') f.seek(0) if content: #非空即真,如果有内容就往下 ...
- Idea_学习_03_IDEA中使自定义类型的文件进行代码高亮识别
如果你只是想用xml的编辑模式来编辑*.screen文件的话,可以在 Settings->Editor->File Types 中,在Recognized File Types选中XML, ...
- javaScript-进阶篇(三)
1.Window对象 window对象是BOM的核心,window对象指当前的浏览器窗口. window对象方法: 2.JavaScript 计时器 在JavaScript中,我们可以在设定的时间间隔 ...
- 《Effective C++》学习笔记(一)
1.const成员函数不能更改成员变量 #include <bits/stdc++.h> using namespace std; class CtextBlock { public: s ...
- Hibernate - 配置c3p0
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuratio ...
- 用WinDbg分析Debug Diagnostic Tool生成的Userdump文件
1.下载WinDbg(Debugging Tools for Windows):http://www.microsoft.com/whdc/devtools/debugging/default.msp ...
- java多线程编程核心技术——第三章总结
第一节等待/通知机制 1.1不使用等待/通知机制实现线程间的通讯 1.2什么是等待/通知机制 1.3等待/通知机制的实现 1.4方法wait()锁释放与notify()锁不释放 1.5当interru ...
- 拓扑排序 POJ 1094 Sorting It All Out
题意:给定N个字和M行他们之间的关系,要求输出他们的拓扑排序.此题采用边输入边检测的方式,如果发现环,就结束并输出当前行号:如果读取到当前行时,可以确定拓扑序列就输出,不管后面的输入(可能包含环路): ...
- Erlang pool management -- Emysql pool
从这篇开始,这一系列主要分析在开源社区中,Erlang 相关pool 的管理和使用. 在开源社区,Emysql 是Erlang 较为受欢迎的一个MySQL 驱动. Emysql 对pool 的管理和使 ...