线程池基础,工作原理与参数设置

线程池的工作主要是控制运行的线程的数量,处理过程中将任务放进队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等待其他线程执行完毕,在从队列中取出任务来执行。

主要特点为:线程复用,控制最大并发数,管理线程


1. 线程池7大参数

线程池基础,工作原理与参数设置_第1张图片

  1. corePoolSize:线程池中的常驻核心线程数
  2. maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于1
  3. keepAliveTime:多余的空闲线程存活时间。当前线程数量超过maximumPoolSize时,当空闲时间达到keepAliveTime时,多余空闲线程会被销毁直到只剩下corePoolSize个线程为止。
  4. unit:keepAliveTime的单位
  5. workQueue:任务队列,被提交但尚未执行的任务
  6. threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程,一般用默认的即可
  7. handler:决绝策略,表示当队列满了并且线程大于线程池的最大线程数(maximumPoolSize)
handler:决绝策略
  • ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ExecutorService threadPool = new ThreadPoolExecutor(2, 5, 1000, TimeUnit.SECONDS, 
				new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), 
				new ThreadPoolExecutor.AbortPolicy());
		
try {
	for (int i = 0; i < 8; i++) {
		threadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + " --> 办理业务");
			}
		});
	}
} finally {
	threadPool.shutdown();
}

线程池基础,工作原理与参数设置_第2张图片

  • ThreadPoolExecutor.CallerRunsPolicy:“调用者运行”一种调节机制,该策略不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用方。
ExecutorService threadPool = new ThreadPoolExecutor(2, 5, 1000, TimeUnit.SECONDS, 
				new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
		
try {
	for (int i = 0; i < 10; i++) {
		threadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + " --> 办理业务");
			}
		});
	}
} finally {
	threadPool.shutdown();
}

回退给main线程调用
线程池基础,工作原理与参数设置_第3张图片

  • ThreadPoolExecutor.DiscardPolicy:直接丢弃任务,不处理任何异常。如果允许任务丢弃,这个是最好的解决方式。
  • ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。
ExecutorService threadPool = new ThreadPoolExecutor(2, 5, 1000, TimeUnit.SECONDS, 
				new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
		
//ExecutorService threadPool = new ThreadPoolExecutor(2, 5, 1000, TimeUnit.SECONDS, 
//		new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy());
		
try {
	for (int i = 0; i < 10; i++) {
		threadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + " --> 办理业务");
			}
		});
	}
} finally {
	threadPool.shutdown();
}

DiscardPolicy和DiscardOldestPolicy丢弃任务,只执行8个线程。
线程池基础,工作原理与参数设置_第4张图片

2. 合理设置线程池参数

2.1 CPU密集型:

CPU密集型也叫计算密集型,指的是系统的硬盘、内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高。

公式:cpu核数 + 1


2.2 IO密集型

IO密集型指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高。

公式1:cpu核数 * 2
公式2:cpu核数 / (1 - 阻塞系数)
阻塞系数 一般是0.8-0.9之间

你可能感兴趣的:(线程,线程参数,java)