zoukankan      html  css  js  c++  java
  • 【转载】Callable、FutureTask中阻塞超时返回的坑点

    本文转载自:http://www.cnblogs.com/starcrm/p/5010863.html

    案例1:

    package com.net.thread.future;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
     
    /**
     * @author 
     * @Time:2017年8月18日 上午10:49:07
     * @version 1.0
     * @description
     */ 
      import java.util.concurrent.ExecutionException;
     import java.util.concurrent.ExecutorService;
     import java.util.concurrent.Executors;
     import java.util.concurrent.FutureTask;
     import java.util.concurrent.TimeUnit;
     import java.util.concurrent.TimeoutException;
      
     public class FutureTaskExample {
      
         public static void main(String[] args) {
             MyCallable callable1 = new MyCallable(1000);
             MyCallable callable2 = new MyCallable(5000);
      
             FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
             FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
      
             ExecutorService executor = Executors.newFixedThreadPool(2);
             executor.execute(futureTask1);
             executor.execute(futureTask2);
              
             while (true) 
             {
                 try {
                     if(futureTask1.isDone() && futureTask2.isDone()){
                         System.out.println("Done");
                         //shut down executor service
                         executor.shutdown();
                         return;
                     }
                      
                     if(!futureTask1.isDone()){
                     //阻塞futureTask1
                     System.out.println("FutureTask1 output="+futureTask1.get());
                     }
                     
                     if(!futureTask2.isDone()){
                     //阻塞futureTask2
                     System.out.println("FutureTask2 output="+futureTask2.get(1000,TimeUnit.MILLISECONDS));
                     }
    
                 } catch (InterruptedException | ExecutionException e) {
                     e.printStackTrace();
                 }catch(Exception e){
                     //do nothing
                 }
             }
              
         }
         
         static class MyCallable implements Callable<String> {
          
             private long waitTime;
              
             public MyCallable(int timeInMillis){
                 this.waitTime=timeInMillis;
             }
             @Override
             public String call() throws Exception {
                 Thread.sleep(waitTime);
                 return Thread.currentThread().getName();
             }
          
         }
     }

    运行结果很简单,必须是:

    FutureTask1 output=pool-1-thread-1
    FutureTask2 output=pool-1-thread-2
    Done

    案例2:

    package com.net.thread.future;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
     
    /**
     * @author 
     * @Time:2017年8月18日 上午10:49:07
     * @version 1.0
     * @description
     */
    public class FutureTaskExample2 {
     
        public static void main(String[] args) {
            MyCallable callable1 = new MyCallable(1000);
            MyCallable callable2 = new MyCallable(5000);
     
            FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
            FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
     
            ExecutorService executor = Executors.newFixedThreadPool(2);
            executor.execute(futureTask1);
            executor.execute(futureTask2);
             
            while (true) 
            {
                 try {
                     if(futureTask1.isDone() && futureTask2.isDone()){
                         System.out.println("Done");
                         //shut down executor service
                         executor.shutdown();
                         return;
                     }
                      
                     if(!futureTask1.isDone()){
                     //阻塞futureTask1
                     System.out.println("FutureTask1 output="+futureTask1.get());
                     }
                      
                     System.out.println("Waiting for FutureTask2 to complete");
                     String s = futureTask2.get(1000, TimeUnit.MILLISECONDS); //阻塞500毫秒
                     if(s !=null){
                         System.out.println("FutureTask2 output="+s);
                     }
                     else{
                         System.out.println("FutureTask2 output is null");
                     }
                 } catch (InterruptedException | ExecutionException e) {
                     e.printStackTrace();
                 }catch(Exception e){
                     //do nothing
                 }  
            }
        }
        
        
        static class MyCallable implements Callable<String> {
         
            private long waitTime;
             
            public MyCallable(int timeInMillis){
                this.waitTime=timeInMillis;
            }
            @Override
            public String call() throws Exception {
                Thread.sleep(waitTime);
                return Thread.currentThread().getName();
            }
         
        }
     
    }

    运行结果:

    FutureTask1 output=pool-1-thread-1
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    FutureTask2 output=pool-1-thread-2
    Done

    说明:

    1、get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;

    2、get(long timeout, TimeUnit unit)用来获取执行结果,如果超过指定时间,直接结束执行下面的代码;如果是在循环中,则跳出本次循环进行下一次轮训(continue功能类似)。

  • 相关阅读:
    MongoDB索引实战技巧
    解决scp/ssh提示输密码慢问题
    mac系统忘记root密码的解决办法
    Javascript DataGrid using the MVC
    便捷的安全检测
    北京出现NW28开头假钞 天津已有相同案例
    12月编程语言排行榜:C#前途无量
    实时股票数据接口大全
    [一定要看完]住在隔壁的刚毕业的大学生小夫妻
    [行業]金山卫士宣布开源 用透明对抗360
  • 原文地址:https://www.cnblogs.com/chen1-kerr/p/7388725.html
Copyright © 2011-2022 走看看