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功能类似)。

 

发布了57 篇原创文章 · 获赞 7 · 访问量 3万+
展开阅读全文

FutureTask异常捕获问题

09-21

如题,我用用FutureTask来监视一个限时任务,但是捕获不到异常,哪位帮忙分析一下。顺便说一下我的功能:我要实现一个流媒体分发的功能,例如同一路视频要分发给不同的用户,流是通过HTTP方式发给客户端,同一路流的所有请求者放在一个LIST里面,如果不限时,当其中一个用户的网路很差的时候就会将列表中其他的用户也堵住,不符合实时流分发的要求,所以要用FutureTask来控制发送时间,如果有哪位兄弟做过类似的东西也可以给我一些意见 1.这是异常 [code="java"] java.lang.InterruptedException at java.lang.Object.wait(Native Method) at org.mortbay.io.nio.SelectChannelEndPoint.blockWritable(SelectChannelE ndPoint.java:279) at org.mortbay.jetty.AbstractGenerator$Output.blockForOutput(AbstractGen erator.java:544) at org.mortbay.jetty.AbstractGenerator$Output.flush(AbstractGenerator.ja va:571) at org.mortbay.jetty.HttpConnection$Output.flush(HttpConnection.java:101 0) at com.hisome.web.httpplayer.thread.RealCallable.call(RealCallable.java: 22) at com.hisome.web.httpplayer.thread.RealCallable.call(RealCallable.java: 13) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor. java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor .java:603) at java.lang.Thread.run(Thread.java:729) 2012-09-21 13:40:14,858 INFO httpplayer.thread.RealCallable -RealCallable write byte IOException [/code] 2.这个是RealCallable的类 [code="java"] public Integer call() throws Exception { try { if (res != null && res.getOutputStream() != null) { res.getOutputStream().write(buffer.array()); res.getOutputStream().flush(); res.flushBuffer(); } } catch (IOException e) { if (e instanceof EOFException) { log.info("RealCallable write byte IOException"); return 1; } } return 0; } [/code] 3.这个是我获取Future的结果的方法体 [code="java"] private void checkTaskResult() { int res = 0; String streamId = null; FutureTask<Integer> future = null; taskIter = taskMap.entrySet().iterator(); while (taskIter.hasNext()) { Entry<String, FutureTask<Integer>> ele = taskIter.next(); streamId = ele.getKey(); future = ele.getValue(); try { res = future.get(10, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { res = 0; } catch (ExecutionException e) { res = 0; } catch (TimeoutException e) { future.cancel(true); res = 0; } catch (CancellationException e) { res = 0; } if (res == 1) { for (StreamInviter inviter : inviters) { if (inviter.getStreamId().equals(streamId)) { inviter.setStatus(false); } } } } } [/code] 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览