Executor框架的使用

//为每一个任务创建一个新线程的缺点:
//①线程的创建与销毁开销很大
//②大量的线程将占据大量的资源,比如内存空间,容易造成服务器资源耗尽而崩溃
//③可创建的线程数量受到操作系统等因素的限制,如果破坏了这些限制,可能抛出异常

//使用Executor将任务的提交与执行解耦,提高程序的并发度,由此获得并发性,并且避免了为每一个任务创建一个新线程产生的问题
class ExecutorTest{
    private static final Executor executor =  Executors.newFixedThreadPool(100);  //该静态方法内部创建的线程池的线程数量固定为100
    public void test() throws IOException{
        ServerSocket serverSocket = new ServerSocket(80);
        while(true){
            Socket conn = serverSocket.accept();
            try{
               executor.execute(new Runnable() {
                   @Override
                   public void run() {
                       handle(conn);
                   }
               });
            }catch (NullPointerException e){
                System.out.println("提交的任务为null");
                e.printStackTrace();
            }catch (RejectedExecutionException e){
                System.out.println("提交的任务无法被Executor接受");
                e.printStackTrace();
            }
        }
    }
    public void handle(Socket socket){
    }
}
//Executor通过创建线程池来处理任务,然而如果Executor无法关闭,那么JVM也不会关闭,因此使用ExecutorService来管理Executor的生命周期
class ExecutorServiceTest{
    private static final ExecutorService executorService = Executors.newFixedThreadPool(100);
    public void test() throws IOException{
        ServerSocket serverSocket = new ServerSocket(80);
        while(!executorService.isShutdown()){
            Socket conn = serverSocket.accept();
            try {
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        handle(conn);
                    }
                });
            }catch (NullPointerException e){
                System.out.println("提交的任务为null");
                e.printStackTrace();
            }catch (RejectedExecutionException e){
                if(!executorService.isShutdown()){
                    System.out.println("提交的任务无法被Executor接受");
                    e.printStackTrace();
                }
            }
        }
    }
    public void stop(){
        executorService.shutdown();
    }
    public void handle(Socket socket){
        if(socket == null){  //这里的判断条件是错误的,正确的判断条件可以是客户端发来的请求是关闭请求
            this.stop();
        }else{

        }
    }
}
//Executor的任务元素是Runnable形式,Runnable没有返回值并且无法抛出异常,在某些情境下是不适用的,因此使用Callale和Future的组合
//由于某些任务是延迟任务,例如页面渲染器可以分解为下载图像(IO密集型)和渲染文本两个过程(CPU密集型),这样可以提高程序的并发性
//Future表示一个任务的生命周期(尚未开始、正在执行、已完成)
class CallableTest{
    private static final ExecutorService executorService = Executors.newFixedThreadPool(100);
    public void test(){
        ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
        Future<ArrayList<ArrayList<Integer>>> future = null;
        while(!executorService.isShutdown()) {
            try {
                future = executorService.submit(new Callable<ArrayList<ArrayList<Integer>>>() {
                    @Override
                    public ArrayList<ArrayList<Integer>> call() throws Exception {
                        return sortAll(lists);
                    }
                });
            }catch (NullPointerException e) {
                System.out.println("提交的任务为null");
                e.printStackTrace();
            }catch (RejectedExecutionException e){
                if(!executorService.isShutdown()){
                    System.out.println("提交的任务无法被Executor接受");
                    e.printStackTrace();
                }
            }
            try {
                ArrayList<ArrayList<Integer>> lists1 = future.get();
                for(int i = 0;i < lists1.size();i++){
                    for(int j = 0;j < lists1.get(i).size();i++){
                        System.out.print(lists1.get(i).get(j)+" ");
                    }
                    System.out.println();
                }
            }catch (CancellationException e){
                System.out.println("任务被取消");
                e.printStackTrace();
            }catch (ExecutionException e){
                System.out.println("任务抛出了异常");
                e.getCause().printStackTrace();  //getCause获取产生异常的真实原因
            }catch (InterruptedException e){  //如果当前线程被中断,抛出该异常
                Thread.currentThread().interrupt();  //清除当前线程的中断标记
                future.cancel(true);
            }
        }

    }
    public ArrayList<ArrayList<Integer>> sortAll(ArrayList<ArrayList<Integer>> lists){
        return null;
    }
}
//CallableTest中如果对数组的排序的速度远高于打印数组的速度,那么其执行效率和串行执行差不多,异构并且存在依赖的任务虽然获得了并发度,但是其并发性可能并没有得到明显的提升
//只有大量相互独立且同构的任务可以并发进行处理时,才能体现出将程序的工作负载分配到多个任务中带来的真正性能提升
//可以通过将一组计算任务分解开,保留与每个任务关联的Future,然后反复使用get来提高程序的响应性(为每一个一维数组创建一个独立的任务,进一步提高并发性)
//Completion:Executor与BlockingQueue的组合使用
class CompletionTest{
    private static final ExecutorService executorService = Executors.newFixedThreadPool(100);
    public void test(){
        ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
        Future<ArrayList<Integer>> future = null;
        while(!executorService.isShutdown()){
            CompletionService<ArrayList<Integer>> completionService = new ExecutorCompletionService<>(executorService);
            try {
                for (int i = 0; i < lists.size(); i++) {
                    int finalI = i;
                    completionService.submit(new Callable<ArrayList<Integer>>() {
                        @Override
                        public ArrayList<Integer> call() throws Exception {
                            return sort(lists.get(finalI));
                        }
                    });
                }
            }catch (NullPointerException e){
                e.printStackTrace();
            }catch (RejectedExecutionException e){
                e.printStackTrace();
            }
            for (int i = 0; i < lists.size(); i++) {
                try {
                    future = completionService.take();
                    ArrayList<Integer> list = future.get();
                    for (int j = 0; j < list.size(); j++) {
                        System.out.print(list.get(j));
                    }
                    System.out.println();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();

                } catch (CancellationException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.getCause().printStackTrace();
                }
            }
        }
    }
    public ArrayList<Integer> sort(ArrayList<Integer> list){
        return null;
    }
}
//如果某个任务在限定时间内无法给出结果,那么抛弃该结果的场景可以使用future.get的有参方法,给出一个时间参数,当抛出TimeOutException时应当取消任务
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值