【高并发系列】17、线程池那些事儿1

时间:2019-02-17
本文章向大家介绍【高并发系列】17、线程池那些事儿1,主要包括【高并发系列】17、线程池那些事儿1使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

多线程软件设计方法可以最大限度地发挥现代多核处理器的计算能力,提高生产系统的吞吐量和性能;

JDK提供的Execotur框架:

1、固定大小线程池newFixedThreadPool

5个固定大小的线程池,提交10个任务,分2批执行任务;

public class ThreadPoolDemo {
	public static class MyTask implements Runnable {
		private String name;
		public MyTask(String name) {
			this.name = name;
		}
		@Override
		public void run() {
			try {
				System.out.println(System.currentTimeMillis() + ":" + this.name + ":" + Thread.currentThread().getName());
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		ExecutorService exec = Executors.newFixedThreadPool(5);
//		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			exec.submit(new MyTask("task" + i));
		}
		exec.shutdown();
	}
}

console

1550367982546:task1:pool-1-thread-2
1550367982546:task2:pool-1-thread-3
1550367982546:task0:pool-1-thread-1
1550367982547:task3:pool-1-thread-4
1550367982547:task4:pool-1-thread-5
1550367983551:task5:pool-1-thread-5
1550367983551:task6:pool-1-thread-1
1550367983552:task7:pool-1-thread-4
1550367983552:task9:pool-1-thread-3
1550367983552:task8:pool-1-thread-2

2、newCachedThreadPool

如果换成Executors.newCachedThreadPool();则直接创建10个线程执行任务,打印如下:

1550369486518:task1:pool-1-thread-2
1550369486518:task0:pool-1-thread-1
1550369486518:task2:pool-1-thread-3
1550369486519:task3:pool-1-thread-4
1550369486519:task4:pool-1-thread-5
1550369486519:task5:pool-1-thread-6
1550369486519:task6:pool-1-thread-7
1550369486520:task7:pool-1-thread-8
1550369486520:task8:pool-1-thread-9
1550369486520:task9:pool-1-thread-10

3、计划任务 ScheduledExecutorService

3.1 scheduleAtFixedRate

任务调度的频率是一定的

public class ScheduledExecutorServiceDemo {
	public static void main(String[] args) {
		ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
		ses.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				try {
					TimeUnit.SECONDS.sleep(1);
					System.out.println(System.currentTimeMillis());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, 0, 3, TimeUnit.SECONDS);
	}
}

任务执行需要先1秒多,任务间隔是3秒,所以打印如下:

1550384755251
1550384758254
1550384761254

如果将任务执行需要1秒改为5秒,即任务执行所需时间5秒大于任务执行间隔,则任务执行完之后立即执行下一个任务,即任务间隔改为5秒;

 

1550384873823
1550384878828
1550384883834

3.2 scheduleWithFixedDelay

任务之间的间隔是一定的

public class ScheduledExecutorServiceDemo {
	public static void main(String[] args) {
		ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
		ses.scheduleWithFixedDelay(new Runnable() {
			@Override
			public void run() {
				try {
					TimeUnit.SECONDS.sleep(1);
					System.out.println(System.currentTimeMillis());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, 0, 3, TimeUnit.SECONDS);
	}
}

任务1秒,间隔3秒,打印出来间隔为4秒:

1550385980234
1550385984244
1550385988253
1550385992261
1550385996265

如果将任务执行需要1秒改为5秒,则打印出来实际间隔为8秒:

1550386073645
1550386081648
1550386089651
1550386097654
1550386105664