线程池ExecutorService

package integral;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Function;

/**
 * 线程池状态
 * 1 runing  线程正在执行中
 * 2 shutingDown  线程池正在关闭中,优雅关闭(线程不再接收新的任务,处理已经接收的任务)
 * 3 terminated  线程池关闭
 * 
 * Executors是顶层类,是执行线程的工具
 * 进程级的重量资源,默认线程池的生命周期和jvm一致.开启后,直到jvm关闭为止
 * shutdown可以关闭线程池,
 * shutdownNow():立即终止线程池并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
 * ExecutorService继承了Excutors,ExecutorService是真正的线程池接口
 * ThreadPoolExecutor是ExecutorService的默认实现
 * @author YangTG
 *
 */
public class ThreadPool {
	
	
	   /**
     * 线程池初始化方法
     *
     * corePoolSize 核心线程池大小----1
     * maximumPoolSize 最大线程池大小----3
     * keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间----30+单位TimeUnit
     * TimeUnit keepAliveTime时间单位----TimeUnit.MINUTES
     * workQueue 阻塞队列----new ArrayBlockingQueue<Runnable>(5)==== 5容量的阻塞队列
     * threadFactory 新建线程工厂----new CustomThreadFactory()====定制的线程工厂
     * rejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,
     * 							即当提交第9个任务时(前面线程都没有执行完,此测试方法中用sleep(100)),
     * 						          任务会交给RejectedExecutionHandler来处理
     */
 

	
	
	public static void main(String[] args) {
		
		ExecutorService excutor = Executors.newFixedThreadPool(100);
		for(int i=0;i<100;i++){
			excutor.execute(new Runnable() {
				
				@Override
				public void run() {
					String str = 
							SpringRestTemplate.getRestTemplate("http://192.168.10.40:8089/security/testController/test", String.class);
					System.out.println(str+":"+Thread.currentThread().getName());
					
				}
			});
		}
		excutor.shutdown();
	}
	
	
	/**
	 * 单线程池,单线程执行所有任务,如果这个线程异常结束会有新的线程替代它
	 * 这个线程保证线程执行顺序是按照认为提交顺序执行
	 * 场景:保证任务顺序执行,秒杀
	 * @throws ExecutionException 
	 * @throws InterruptedException 
	 */
	public void simpleThreadPool() throws InterruptedException, ExecutionException{
		
		ExecutorService excutor = Executors.newSingleThreadExecutor();
		excutor.execute(new Runnable() {
			
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName());
				System.out.println(Thread.currentThread().getState());
				
			}
		});
		//excutor.shutdown();
		System.out.println("是否关闭:"+excutor.isShutdown());
		System.out.println("是否Terminated:"+excutor.isTerminated());
		
		//关闭线程池后,不能在执行线程池
		/*excutor.execute(new Runnable() {
			@Override
			public void run() {
				
				System.out.println("shutdown在执行线程池:"+Thread.currentThread().getName());
			}
		});*/
		
		Future<String> future = excutor.submit(new Callable<String>() {

			@Override
			public String call() throws Exception {
				// TODO Auto-generated method stub
				return Thread.currentThread().getName();
			}
		});
		System.out.println(future);
		System.out.println("futur.isDone():"+future.isDone());//查看任务是否执行结束
		System.out.println("future.get():"+future.get());//获取call的返回值
		System.out.println("futur.isDone():"+future.isDone());
	}
	
	/**
	 * 创建一个固定大小的线程池
	 * 每次提交一个认为就会创建一个线程,直到达到线程池最大大小.如果某个线程异常结束,
	 * 那么线程池会补充一个新的线程
	 * 使用的是LinkedBlockingQueue<Runnable>作为任务载体,任务数量大于线程池的数量时候
	 * 没有运行的任务保存在队列里,当有空闲的线程时候,会从队列里去出来
	 * 使用场景:大多数使用的场景首选,os系统的线程数量有限
	 * 一般pc 线程数100 服务器:1000-5000
	 * 并发能力 线程*10到18之间
	 */
	public void fixedThreadPool(){
		
		ExecutorService excutor = Executors.newFixedThreadPool(4);
			 
		 
	}
	
	
	/**
	 * 可以缓冲的线程池,没有上限,自动扩容
	 * 容量管理策略 
	 * 如果线程池大小超过了当前任务所需的线程,就会回收部分空闲线程
	 * 当任务增加后,会智能添加新线程来处理任务。
	 * 此线程池不会限定大小,会依赖当前操作系统能够创建最大线程数
	 * 场景:内部应用,内部数据瞬间处理。测试应用:尝试硬件或者软件的最高负载量
	 */
	public void cachadThreadPool(){
		
		ExecutorService excutor = Executors.newCachedThreadPool();
		excutor.execute(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				
			}
		});
		
	}
	
	/**
	 * 创建大小不限的线程池.这个线程支持定时和周期性任务
	 * 阻塞,效率低下
	 * 场景 :计划任务,数据整理
	 */
	public void scheduleThreadPool(){
		
		ExecutorService excutor = Executors.newScheduledThreadPool(1);
	}
	
	public void function(String a,Function<String, String> f){
		f.apply(a);
	}
}
package common.test;

import com.alibaba.fastjson.JSONObject;
import com.fast.cattsoft.util.HttpClientUtil;
import com.google.common.collect.Lists;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test2 {

    public static void main(String[] args) {
        List<String> skus  = param();
        //集合拆分
        int limit = (skus.size() + 20 - 1) / 20;
        List<List<String>> collect = Stream.iterate(0, f -> f + 1).limit(limit).parallel()
                .map(ma -> {
                    return skus.parallelStream().skip(ma * 20).limit(20).collect(Collectors.toList());
                }).collect(Collectors.toList());

        //拆分的集合大于1 使用线程池
        if (collect.size() > 1) {
            LocalDateTime start = null;
            System.out.println("start" + (start = LocalDateTime.now()));
            //定义线程池
            ThreadPoolExecutor pool = new ThreadPoolExecutor(2,
                    4,
                    2000,
                    TimeUnit.MILLISECONDS,
                    new ArrayBlockingQueue<>(10));
           
            List<List<BuyerPriceInfoVo>> collect1 = collect.stream().map(ma -> {

                // 定义线程池认为  Callable可以返回值
                Callable<List<BuyerPriceInfoVo>> callableList = new Callable<List<BuyerPriceInfoVo>>() {
                    @Override
                    public List<BuyerPriceInfoVo> call() throws Exception {
                        UriComponentsBuilder https = UriComponentsBuilder.newInstance()
                                .scheme("https")
                                .host("inv.dev.platform.michaels.com/api")
                                .path("/price/master-sku");
                        ma.stream().forEach(a -> {
                            https.queryParam("masterSkuNumbers", a);
                        });
                        UriComponents uri = https.build();
                        return HttpClientUtil.okHttpGet(uri.toString(), BuyerPriceInfoVo.class);
                    }
                };
                return callableList;
            }).map(ma1 -> {
                try {
                    //提交任务
                    return pool.submit(ma1).get();
                } catch (Exception e) {
                    throw new RuntimeException("");
                }
            }).collect(Collectors.toList());
            LocalDateTime end = null;
            System.out.println("end" + (end = LocalDateTime.now()));
            System.out.println(Duration.between(start, end).getSeconds());
            if (!CollectionUtils.isEmpty(collect1)) {
                System.out.println(JSONObject.toJSON(collect1));
            } else {
                System.out.println("masterSkuNumbers is null");
            }
            pool.shutdownNow();
            System.out.println("pool shutdown");
        } else {
            UriComponentsBuilder https = UriComponentsBuilder.newInstance()
                    .scheme("http")
                    .host("192.168.2.36")
                    .path("/price/master-sku");
            collect.stream().forEach(a -> {
                https.queryParam("masterSkuNumbers", a);
            });
            UriComponents uri = https.build();
            try {
                HttpClientUtil.okHttpGet(uri.toString(), BuyerPriceInfoVo.class);
            } catch (Exception e) {
                throw new RuntimeException("");
            }
        }
        System.out.println("end");
    }
    //构建请求参数
    public static List<String> param(){
        List<String> skus = Lists.newArrayList();
        skus.add("59335331566");
        skus.add("59335368331");
        skus.add("59334827165");
        skus.add("59334169520");
        skus.add("59334071938");
        skus.add("59333662026");
        skus.add("59325940362");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335368331");
        skus.add("59334827165");
        skus.add("59334169520");
        skus.add("59334071938");
        skus.add("59333662026");
        skus.add("59325940362");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        skus.add("59335331566");
        return skus;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,可以使用配置类来配置Executor线程池。其中,常用的实现类是`ExecutorService`和`ThreadPoolTaskExecutor`。 首先,需要创建一个配置类,可以命名为`ThreadPoolConfig`或者其他你喜欢的名称。在这个类中,你需要使用`@Configuration`注解来标识它是一个配置类,并且使用`@EnableAsync`注解来启用异步执行。 接下来,你需要定义一个`ExecutorService`或`ThreadPoolTaskExecutor` Bean,并使用`@Bean`注解将其标识为一个Bean。你可以根据项目的需求来选择使用哪个实现类。 如果选择使用`ExecutorService`,可以按照以下方式配置: ```java @Configuration @EnableAsync public class ThreadPoolConfig { @Bean public ExecutorService executorService() { return Executors.newFixedThreadPool(10); // 配置线程池的大小 } } ``` 如果选择使用`ThreadPoolTaskExecutor`,可以按照以下方式配置: ```java @Configuration @EnableAsync public class ThreadPoolConfig { @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); // 设置核心线程数 executor.setMaxPoolSize(20); // 设置最大线程数 executor.setQueueCapacity(30); // 设置队列容量 executor.setThreadNamePrefix("my-executor-"); // 设置线程名称前缀 executor.initialize(); // 初始化 return executor; } } ``` 在上述配置中,你可以根据实际需求来设置线程池的大小、队列容量等参数。通过这种方式,你就可以在应用程序中注入`ExecutorService`或`ThreadPoolTaskExecutor`,并使用它来执行异步任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值