一、多线程任务类型
多线程任务类型分为CPU 密集型以及I/O 密集型任务
CPU 密集型
* 这种任务消耗的主要是 CPU 资源,可以将线程数设置为 N(CPU 核心数)+1,
* 比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。
* 一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间。
I/O 密集型任务
* 这种任务应用起来,系统会用大部分的时间来处理 I/O 交互,而线程在处理 I/O 的时间段内
* 不会占用 CPU 来处理,这时就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务的应用中,
* 我们可以多配置一些线程,具体的计算方法是 2N。
二、代码示例
1.CPU 密集型
package com.yl.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Vector;
/**
* 多线程任务类型CPU 密集型
* 这种任务消耗的主要是 CPU 资源,可以将线程数设置为 N(CPU 核心数)+1,
* 比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。
* 一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间。
* @author toshiba
* @date 2020/5/25
*/
@Component
@Slf4j
public class CpuTypeThread implements Runnable{
/**
* 线程名称
*/
int threadNext = 0;
/**
* 整体执行时间,包括在队列中等待的时间
*/
List<Long> wholeTimeList;
/**
* 真正执行时间
*/
List<Long> runTimeList;
private long initStartTime = 0;
/**
* 构造函数
* @param runTimeList
* @param wholeTimeList
*/
public CpuTypeThread(List<Long> runTimeList, List<Long> wholeTimeList, int threadNext) {
initStartTime = System.currentTimeMillis();
this.runTimeList = runTimeList;
this.wholeTimeList = wholeTimeList;
this.threadNext = threadNext;
}
/**
* 判断素数
* @param number
* @return
*/
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;
}
/**
* 計算素数
* @param lower
* @param upper
* @return
*/
public int countPrimes(final int lower, final int upper) {
int total = 0;
for (int i = lower; i <= upper; i++) {
if (isPrime(i)) {
total++;
}
}
return total;
}
@Override
public void run() {
long start = System.currentTimeMillis();
countPrimes(1, 1000000);
long end = System.currentTimeMillis();
long wholeTime = end - initStartTime;
long runTime = end - start;
wholeTimeList.add(wholeTime);
runTimeList.add(runTime);
log.info(" CpuTypeThread-"+threadNext+"-- 单个线程花费时间:" + (end - start));
}
}
2.I/O 密集型任务
package com.yl.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;
/**
* I/O 密集型任务
* 这种任务应用起来,系统会用大部分的时间来处理 I/O 交互,而线程在处理 I/O 的时间段内
* 不会占用 CPU 来处理,这时就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务的应用中,
* 我们可以多配置一些线程,具体的计算方法是 2N。
* @author toshiba
* @date 2020/5/25
*/
@Component
@Slf4j
public class IoTypeThread implements Runnable{
/**
* 线程名称
*/
int threadNext = 0;
/**
* 整体执行时间,包括在队列中等待的时间
*/
Vector<Long> wholeTimeList;
/**
* 真正执行时间
*/
Vector<Long> runTimeList;
private long initStartTime = 0;
/**
* 构造函数
* @param runTimeList
* @param wholeTimeList
*/
public IoTypeThread(Vector<Long> runTimeList, Vector<Long> wholeTimeList, int threadNext) {
initStartTime = System.currentTimeMillis();
this.runTimeList = runTimeList;
this.wholeTimeList = wholeTimeList;
this.threadNext = threadNext;
}
/**
* IO 操作
* @throws IOException
*/
public void readAndWrite() throws IOException {
File sourceFile = new File("D:/YlDream/path.txt");
// 创建输入流
BufferedReader input = new BufferedReader(new FileReader(sourceFile));
// 读取源文件, 写入到新的文件
String line = null;
while((line = input.readLine()) != null){
}
// 关闭输入输出流
input.close();
}
@Override
public void run() {
long start = System.currentTimeMillis();
try {
readAndWrite();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
long wholeTime = end - initStartTime;
long runTime = end - start;
wholeTimeList.add(wholeTime);
runTimeList.add(runTime);
log.info(" IoTypeThread-"+threadNext+"-- 单个线程花费时间:" + (end - start));
}
}
测试
package com.yl.test;
import com.yl.util.CpuTypeThread;
import com.yl.util.IoTypeThread;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.*;
/**
* 线程池定义
* @author toshiba
* @date 2020/5/25
*/
@Slf4j
public class ThreadTest {
/**
* 核心池的大小
*/
private final static int corePoolSize = 5;
/**
* 线程池最大线程数
*/
private final static int maximumPoolSize = 10;
/**
* 线程没有任务执行时最多保持多久时间会终止
*/
private final static long keepAliveTime = 100;
/**
* 参数keepAliveTime的时间单位,有7种取值
* TimeUnit.DAYS; //天
* TimeUnit.HOURS; //小时
* TimeUnit.MINUTES; //分钟
* TimeUnit.SECONDS; //秒
* TimeUnit.MILLISECONDS; //毫秒
* TimeUnit.MICROSECONDS; //微妙
* TimeUnit.NANOSECONDS; //纳秒
*/
private final static TimeUnit unit = TimeUnit.SECONDS;
/**
* 一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响
* ArrayBlockingQueue;
* LinkedBlockingQueue;
* SynchronousQueue;
* ArrayBlockingQueue和PriorityBlockingQueue使用较少,一般使用LinkedBlockingQueue
* 和Synchronous。线程池的排队策略与BlockingQueue有关。
*/
private final static BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue();
/**
* 线程工厂,主要用来创建线程
*/
private final static ThreadFactory threadFactory = null;
/**
* 表示当拒绝处理任务时的策略,有以下四种取值:
* ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
* ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
* ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
* ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
*/
private final static RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, maximumPoolSize, keepAliveTime,
unit, workQueue, handler);
CpuTypeThread thread;
IoTypeThread threadI;
List<Long> runTimeList = new ArrayList<>();
List<Long> wholeTimeList = new ArrayList<>();
Vector<Long> runTimeListV = new Vector<>();
Vector<Long> wholeTimeListV = new Vector<>();
for(int i = 0; i < 150; i++){
thread = new CpuTypeThread(runTimeList, wholeTimeList, i);
executor.execute(thread);
log.info("thread-线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行完的任务数目:"+executor.getCompletedTaskCount());
threadI = new IoTypeThread(runTimeListV, wholeTimeListV, i);
executor.execute(threadI);
log.info("threadI-线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行完的任务数目:"+executor.getCompletedTaskCount());
}
executor.shutdown();
}
}
以上