异步线程池ThreadPoolTaskExecutor-内嵌js规则验证

 scheduling包下    org.springframework.scheduling.concurrent

最大线程数不能维持太多
        ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
        ex.setThreadNamePrefix("my-ex");
        ex.setCorePoolSize(2);
        ex.setKeepAliveSeconds(3000);
        ex.setMaxPoolSize(3);
        ex.setQueueCapacity(2);//不设置默认21亿
        ex.initialize();
同时执行6个请求,会丢弃一个
ex.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
多出来的线程由主线程执行


结论: future2在get之前已经释放线程
现象: 访问/testAsyn2时,用的my-ex2线程,没有用主线程
      如果get之前没有释放线程,那么第一个请求/testAsyn已经把线程耗尽,访问/testAsyn2时则会用主线程
@Configuration
public class MyConfig {
    @Bean(name="myTaskExcuter")
    public ThreadPoolTaskExecutor myExecutor(){
        ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
        ex.setThreadNamePrefix("my-ex");
        ex.setCorePoolSize(2);
        ex.setKeepAliveSeconds(3000);
        ex.setMaxPoolSize(2);
        ex.setQueueCapacity(0);
        ex.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy());
        ex.initialize();
        return ex;
    }
}

   @GetMapping(value = "/testAsyn")
    public String testAsyn(){
        MyTask mt = new MyTask();
        MyTask2 mt2 = new MyTask2();
        MyTask3 mt3 = new MyTask3();
        Future<String> future = myTaskExcuter.getThreadPoolExecutor().submit(mt);
        Future<String> future2 = myTaskExcuter.getThreadPoolExecutor().submit(mt2);
        Future<String> future3 = myTaskExcuter.getThreadPoolExecutor().submit(mt3);
        String f = future.get();
        log.info("testAsyn***before-f2");
        String f2 = future2.get();
        String f3 = future3.get();
        log.info(f+","+f2+","+f3);
        return "success";
    }

    @SneakyThrows
    @GetMapping(value = "/testAsyn2")
    public String testAsyn2(){
        MyTask3 mt3 = new MyTask3();
        Future<String> future3 = myTaskExcuter.getThreadPoolExecutor().submit(mt3);
        String f3 = future3.get();
        log.info(f3);
        return "success";
    }

@Slf4j
public class MyTask implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(10000);
        log.info("***************MyTask");
        System.out.println(Thread.currentThread().getName()+",task.calltest");
        return "MyTask";
    }
}
@Slf4j
public class MyTask2 implements Callable<String> {
    @Override
    public String call() throws Exception {
        log.info("***************MyTask2");
        System.out.println(Thread.currentThread().getName()+",MyTask2");
        return "MyTask2";
    }
}
@Slf4j
public class MyTask3 implements Callable<String> {
    @Override
    public String call() throws Exception {
        log.info("***************MyTask3");
        System.out.println(Thread.currentThread().getName()+",MyTask3");
        return "MyTask3";
    }
}

 

@Async注解实现异步任务
同样是任务执行完就释放线程,无需等get

    @GetMapping(value = "/testCompletable")
    public String testCompletable() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cfuture = completableTask.completableTask("ctask");
        CompletableFuture<String> cfuture2 = completableTask.completableTask2("ctask2");
        CompletableFuture.allOf(cfuture,cfuture2).join();
        log.info(cfuture.get()+","+cfuture2.get());
        return "success";
    }
    @GetMapping(value = "/testCompletable2")
    public String testCompletable2() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cfuture2 = completableTask.completableTask2("ctask3");
        log.info(","+cfuture2.get());
        return "success";
    }

@Slf4j
@Component
public class CompletableTask {
    @SneakyThrows
    @Async("myTaskExcuter")
    public CompletableFuture<String> completableTask(String param){
        Thread.sleep(10000);
        log.info(Thread.currentThread().getName()+"******completableTask");
        return CompletableFuture.completedFuture(param);
    }
    @Async("myTaskExcuter")
    public CompletableFuture<String> completableTask2(String param){
        log.info(Thread.currentThread().getName()+"******completableTask2");
        return CompletableFuture.completedFuture(param);
    }
}

@EnableAsync
@Configuration
public class MyConfig {
    @Bean(name="myTaskExcuter")
    public ThreadPoolTaskExecutor myExecutor(){
        ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
        ex.setThreadNamePrefix("my-ex");
        ex.setCorePoolSize(2);
        ex.setKeepAliveSeconds(3000);
        ex.setMaxPoolSize(2);
        ex.setQueueCapacity(0);
        ex.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy());
        ex.initialize();
        return ex;
    }
}

 

 使用js相关API进行规则校验

param="age,days";
rule="age > 50 || days < 28";
List list = [19,21313天];
Object[] toArray=list.toArray();

ScriptEngineManager sem = new ScriptEnginerManager();
ScriptEngine engine = sem.getEngineByName("js");
String script="function compare("+param+"){return "+rule+";}";
engine.eval(script);
Invocable invoke = (Invocable)engine;
boolean matching = (boolean)invoke.invokeFunction("compare",toArray);

 

当前线程”在调用wait()/notify()时,必须拥有该对象的同步锁 高并发使用对象池实例
1,初始化对象池,3个对象
2,获取对象并移除 同步锁
3,释放对象,通知等待获取对象的线程,同步锁

public class PoolUtils {

	private List<Domain> list;
	
	public void init(){
		list = new ArrayList<Domain>();
		for(int i = 0; i < 3; i++){
			list.add(new Domain());
		}
	}
	
	public synchronized Domain getDomain(){
		Domain domain = null;
		if(list.size()>0){
			domain = list.remove(0);
			System.out.println(Thread.currentThread().getName()+",get left:"+list.size());
		} else {
			try {
				System.out.println(Thread.currentThread().getName()+":wait before");
				wait();
				System.out.println(Thread.currentThread().getName()+":wait after");
			} catch (Exception e) {
				System.out.println("getException:"+e.getMessage());
				e.printStackTrace();
			}
			domain = getDomain();
		}
		return domain;
	}
	
	public synchronized void returnDomain(Domain domain){
		list.add(domain);
		System.out.println(Thread.currentThread().getName()+",return left:"+list.size());		
		notifyAll();
//		notify();
	}
}

  

public static void main(String[] args) {
		final PoolUtils pu = new PoolUtils();//单例
		
		pu.init();
		
		Thread t1 = new Thread(){
			public void run(){
				Domain dom = pu.getDomain();
				System.out.println(Thread.currentThread().getName()+":get domain:"+dom);
                try {
					Thread.currentThread().sleep(3000);
				} catch (Exception e) {
					System.out.println("getExceptionT:"+e.getMessage());
					e.printStackTrace();
				}
                pu.returnDomain(dom);
                System.out.println(Thread.currentThread().getName()+":return domain:"+dom);
			}
		};
		Thread t2 = new Thread(){ 。。。。。。。。。

  

 

posted @ 2020-03-01 17:43  XUMT111  阅读(289)  评论(0编辑  收藏  举报