栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java线程池初步学习及使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java线程池初步学习及使用

Java线程池初步学习及使用
  • 了解线程池
  • 线程池工作原理
    • corePoolSize :
    • maximumPoolSize :
    • workQueue:
    • KeepAliveTime:
    • workQueue 任务队列:
    • threadFactory:
    • handler 拒绝策略:
      • 4种拒绝策略
  • ThreadPoolExecutor.AbortPolicy()
  • ThreadPoolExecutor.CallerRunsPolicy()
  • ThreadPoolExecutor.DiscardPolicy()
  • ThreadPoolExecutor.DiscardOldestPolicy()
  • 线程池相关接口介绍:
  • submit方法示例:

了解线程池

1.什么是线程池?
(首先要理解什么是线程)
线程池,thread pool,是一种线程使用模式,线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。

通俗来说,就是可管理和维护以及分配线程的“池子”。
2.为什么使用线程池?
在实际开发中,线程是宝贵资源,为了减少创建和销毁线程的次数,让每个线程都可以多次的使用,可以根据系统情况调整线程的数量,防止消耗过多内存。在实际使用中,服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,使用线程池就可以优化。
线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重复使用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使用应用程序响应更快。

线程池工作原理

让我们来首先看下ThreadPoolExecutor的构造方法:

public ThreadPoolExecutor (
       int corePoolSize,
       int maximumPoolSize,
       long keepAliveTime,
       TimeUnit unit,
       BlockingQueue workQueue,
       ThreadFactory threadfactory,
       RejectedExecutorHandler handler) {
       //略,实现方法部分
 }

corePoolSize :

线程池中核心线程数的最大
值

maximumPoolSize :

线程池中能拥有最多线程数

workQueue:

用于缓存任务的阻塞队列当调用线程池execute() 方法添加一个任务时,线程池会做如下判断:如果有空闲线程,则直接执行该任务;如果没有空闲线程,且当前运行的线程数少于corePoolSize,则创建新的线程执行该任务;如果没有空闲线程,且当前的线程数等于corePoolSize,同时阻塞队列未满,则将任务入队列,而不添加新的线程;如果没有空闲线程,且阻塞队列已满,同时池中的线程数小于maximumPoolSize ,则创建新的线程执行任务;如果没有空闲线程,且阻塞队列已满,同时池中的线程数等于maximumPoolSize ,则根据构造函数中的 handler 指定的策略来拒绝新的任务。

KeepAliveTime:

keepAliveTime :表示空闲线程的存活时间TimeUnit unit :表示keepAliveTime的单位当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。注:如果线程池设置了allowCoreThreadTimeout参数为true(默认false),那么当空闲(包括核心线程)线程超过keepaliveTime后直接停掉。(不会判断线程数是否大于corePoolSize)即:最终线程数会变为0。

workQueue 任务队列:

workQueue :它决定了缓存任务的排队策略ThreadPoolExecutor线程池推荐了三种等待队列,它们是:SynchronousQueue 、LinkedBlockingQueue 和 ArrayBlockingQueue。

threadFactory:

threadFactory :指定创建线程的工厂。(可以不指定)如果不指定线程工厂时,ThreadPoolExecutor 会使用ThreadPoolExecutor.defaultThreadFactory 创建线程。

handler 拒绝策略:

handler :表示当 workQueue 已满,且池中的线程数达到 maximumPoolSize 时,线程池拒绝添加新任务时采取的策略。(可以不指定)

4种拒绝策略 ThreadPoolExecutor.AbortPolicy()

若线程池已满,抛出RejectedExecutionException异常。默认策略

ThreadPoolExecutor.CallerRunsPolicy()

由向线程池正在执行的worker来执行该任务

ThreadPoolExecutor.DiscardPolicy()

不报错,直接丢弃此线程

ThreadPoolExecutor.DiscardOldestPolicy()

抛弃最旧的任务(最先提交而没有得到执行的任务)并将自己添加到队列中

线程池相关接口介绍:

1、ExecutorService接口:

该接口是真正的线程池接口。上面的ThreadPoolExecutor以及下面的ScheduledThreadPoolExecutor都是该接口的实现类。改接口常用方法:
public Future submit(Runnable task):提交Runnable任务到线程池,返回Future对象,由于Runnable没有返回值,也就是说调用Future对象get()方法返回null;
public Future submit(Callable task):提交Callable任务到线程池,返回Future对象,调用Future对象get()方法可以获取Callable的返回值;
Future submit(Runnable task,T result):提交Runnable任务到线程池,返回Future对象,调用Future对象get()方法可以获取Runnable的参数值;
invokeAll(collection of tasks)/invokeAll(collection of tasks, long timeout, TimeUnit unit):invokeAll会按照任务集合中的顺序将所有的Future添加到返回的集合中,该方法是一个阻塞的方法。只有当所有的任务都执行完毕时,或者调用线程被中断,又或者超出指定时限时,invokeAll方法才会返回。当invokeAll返回之后每个任务要么返回,要么取消,此时客户端可以调用get/isCancelled来判断具体是什么情况。
invokeAny(collection of tasks)/invokeAny(collection of tasks, long timeout, TimeUnit unit):阻塞的方法,不会返回 Future 对象,而是返回集合中某一个Callable 对象的结果,而且无法保证调用之后返回的结果是哪一个 Callable,如果一个任务运行完毕或者抛出异常,方法会取消其它的 Callable 的执行。和invokeAll区别是只要有一个任务执行完了,就把结果返回,并取消其他未执行完的任务;同样,也带有超时功能;
public void shutdown():在完成已提交的任务后关闭服务,不再接受新任;
public void shutdownNow():停止所有正在执行的任务并关闭服务;
public boolean isTerminated():测试是否所有任务都执行完毕了;
public boolean isShutdown():测试是否该ExecutorService已被关闭。

submit方法示例:

我们知道,线程池接口中有以下三个主要方法,接下来我们看一下具体示例:

1)Callable:

public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 50, 300, TimeUnit.SECONDS, 
			new ArrayBlockingQueue(50),  
			new ThreadFactory(){ public Thread newThread(Runnable r) {
                return new Thread(r, "schema_task_pool_" + r.hashCode());
            }}, new ThreadPoolExecutor.DiscardOldestPolicy());
 
public static void callableTest() {
	int a = 1;
	//callable
	Future future = threadPool.submit(new Callable(){
		@Override
		public Boolean call() throws Exception {
			int b = a + 100;
			System.out.println(b);
			return true;
		}
	});
	try {
		System.out.println("feature.get");
		Boolean boolean1 = future.get();
		System.out.println(boolean1);
	} catch (InterruptedException e) {
		System.out.println("InterruptedException...");
		e.printStackTrace();
	} catch (ExecutionException e) {
		System.out.println("execute exception...");
		e.printStackTrace();
	} 
}

2)Runnable

public static void runnableTest() {
	int a = 1;
	//runnable
	Future future1 = threadPool.submit(new Runnable(){
		@Override
		public void run() {
			int b = a + 100;
			System.out.println(b);
		}
	});
	try {
		System.out.println("feature.get");
		Object x = future1.get(900,TimeUnit.MILLISECONDS);
		System.out.println(x);//null
	} catch (InterruptedException e) {
		e.printStackTrace();
	} catch (ExecutionException e) {
		System.out.println("execute exception...");
		e.printStackTrace();
	} catch (TimeoutException e) {
		e.printStackTrace();
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993466.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号