java多线程 线程池的使用

java线程池

        • 说明
        • 实例
        • 总结

说明

目前大家有在使用的,例如数据库连接池等其他的池技术,可以有效使用资源,方便控制,线程池也是如此,目前线程的使用都是从线程池,很少自己单独创建,维护线程的使用。

java多线程 线程池的使用_第1张图片

实例

package com.example.demo.pool;

import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class PoolTest {
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		ThreadPoolExecutor pool = new ThreadPoolExecutor(10,20,6,TimeUnit.SECONDS,new ArrayBlockingQueue(20),new ThreadPoolExecutor.CallerRunsPolicy());
		
		for(int i = 0 ;i<3;i++) {
			Runnable work = new MyThreadTest();
			pool.execute(work);
		}
		
		
		
		for(int i = 0 ;i<3;i++) {
			Callable work1 = new MyThreadCallTest();
			Future future   = pool.submit(work1);
			System.out.println("接收到的参数:"+ String.valueOf(future.get()));
		}
		
		
		
	}

}


  class  MyThreadTest implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		//synchronized (MyThreadTest.class) {
			System.out.println("当前的Call流程:"+Thread.currentThread().getName()+"开始"+new Date());
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("当前的Call流程:"+Thread.currentThread().getName()+"结束"+new Date());
		//}
	}
	
	
}
  
  
  
 class MyThreadCallTest implements Callable<String>{

	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		
		//synchronized (MyThreadCallTest.class) {
			System.out.println("当前的流程:"+Thread.currentThread().getName()+"开始"+new Date());
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("当前的流程:"+Thread.currentThread().getName()+"结束"+new Date());
	//	}
		
		return Thread.currentThread().getName()+"返回结果";
	}
	 
	 
	 
	 
 }  





总结

降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的资源浪费。
提高响应速度。当任务到达时,不需要等到线程创建就能立即执行。
方便管理线程。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以对线程进行统一的分配,优化及监控。
  1. 参数 corePoolSize

    表示线程池的常驻核心线程数。如果设置为 0,则表示在没有任何任务时,销毁线程池;如果大于 0,即使没有任务时也会保证线程池的线程数量等于此值;
    应该结合实际业务设置此值的大小。若 corePoolSize 的值较小,则会出现频繁创建和销毁线程情况;若值较大,则会浪费系统资源。

  2. 参数 maximumPoolSize

    表示线程池最大可以创建的线程数。官方规定此值必须大于 0,也必须大于等于 corePoolSize 的值;
    此值只有在任务比较多,且不能存放在任务队列时,才会用到。

  3. 参数 keepAliveTime

    表示线程的存活时间。当线程池空闲时并且超过了此时间,多余的线程就会销毁,直到线程池中的线程数等于 corePoolSize 的值为止;
    若 maximumPoolSize 的值 等于 corePoolSize 的值,则线程池在空闲的时候不会销毁任何线程。

  4. 参数 unit

    表示存活时间的单位,配合 keepAliveTime 参数共同使用。

  5. 参数 workQueue

    表示线程池执行的任务队列;
    当线程池的所有线程都在处理任务时,若来了新任务则会缓存到此任务队列中,然后等待执行。

  6. 参数 threadFactory

    表示线程的创建工厂,一般使用默认的线程创建工厂的方法 Executors.defaultThreadFactory()来创建线程。

  7. 参数 RejectedExecutionHandler

    表示指定线程池的拒绝策略,属于一种限流保护的机制;
    当线程池的任务已经在缓存队列 workQueue 中存满了之后,并且不能创建新的线程来执行此任务时,就会用到此拒绝策略
    四种拒绝策略
    (1) AbortPolicy: 丢弃任务并抛出异常。
    (2) DiscardPolicy:丢弃任务但不抛出异常。
    (3) DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务
    (4) CallerRunsPolicy:由调用线程处理该任务

    submit() 方法可以配合 Future来接收线程执行的返回值,而 execute() 不能接收返回值;
    execute() 方法属于 Executor 接口的方法,而 submit() 方法则是属于 ExecutorService 接口的方法。

你可能感兴趣的:(java面试)