Java_多线程_线程池

我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是会有一个问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率。
那么有没有一种办法使得线程可以复用,执行完一个任务,并不被销毁,而是可以继续执行其他任务。
在Java中通过线程池达到这样的效果,java.util.concurrent.ThreadPoolExcutor类时线程池中最核心的一个类
并发API引入了ExecutorService作为一个在程序中直接使用Thread的高层次替换方案。Executors支持运行异步任务,通常管理一个线程池,这样一来我们就不需要手动去创建新线程。在不断处理任务的过程中,线程池内部线程将会得到复用,因此,我们可以使用一个executorService来运行整个程序中需要并发执行的任务。
Executors类提供了便利的工厂方法来创建不同类型的executorService。
Executors必须显式地停止,否则将持续监听新的任务,executorService提供了两个方法:

  • shutdown() 等待正在执行的任务执行完
  • shutdownNow() 终止所有正在执行的任务并立即关闭
package com.test.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ThreadPoolTest {
	
	public static void main(String[] args) {
		// 1. 线程池 :作用提高线程对象的复用性
		// 2. 创建线程池
		// 2.1 创建一个单一的线程对象的线程池对象  只管理一个线程对象
//		ExecutorService service = Executors.newSingleThreadExecutor();
		
		// 2.2创建一个可以创建多个线程对象的线程池 如果有现成的线程对象 直接用,没有的话创建新的 
		// 如果一个线程对象60s钟没用被使用,则将其对象移除
//		ExecutorService service = Executors.newCachedThreadPool();
		
		// 2.3 创建一个固定线程对象的线程池 
		ExecutorService service = Executors.newFixedThreadPool(2);
		
		// 创建任务对象
		Runnable task1 = new Runnable() {
			@Override
			public void run() {
				for(int i=0;i<5;i++) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread()+"--->task 1 "+i);
					
				}
			}
		};
		Runnable task2 = new Runnable() {
			@Override
			public void run() {
				for(int i=0;i<5;i++) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread()+"--->task 2  "+i);
				}
			}
		};
		// 提交一个任务
		service.submit(task1);
//		try {
//			Thread.sleep(1000);
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		service.submit(task2);
//		try {
//			Thread.sleep(3000);
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		service.submit(task1);
//		service.submit(task2);
//		
		
		// 3. 退出程序
		service.shutdown(); // 会将之前要已经提交过的 任务全部执行完成之后 关闭程序 之后再提交的任务会被拒绝
		
//		service.submit(task1);
		
		try {
			// 阻塞方法 在shutdown方法调用后调用该方法 直到线程池中的任务执行完成或者时间超时之后执行之后的代码
			// 返回值true 表示所有任务执行完成 false表示超时,有部分任务没有执行完
			boolean b = service.awaitTermination(200, TimeUnit.SECONDS);
			System.out.println(b);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

发布了359 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Chill_Lyn/article/details/104134835
今日推荐