欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈在Java中使用Callable、Future进行并行编程

程序员文章站 2023-12-04 11:41:58
使用callable、future进行并行编程 在java中进行并行编程最常用的方式是继承thread类或者实现runnable接口。这两种方式的缺点是在任务完成后无法直...

使用callable、future进行并行编程

在java中进行并行编程最常用的方式是继承thread类或者实现runnable接口。这两种方式的缺点是在任务完成后无法直接获取执行结果,必须通过共享变量或线程间通信,使用起来很不方便。

从java1.5开始提供了callable和future两个接口,通过使用它们可以在任务执行完毕后得到执行结果。

下面我们来学习下如何使用callable、future和futuretask。

callable接口

callable接口位于java.util.concurrent包,这是一个泛型接口,里面只声明了一个call()方法:

public interface callable<t> {
  t call() throws exception;
}

一般配合executorservice接口来使用它,在executorservice接口中声明了几个重载的submit方法:

<t> future<t> submit(callable<t> task);
<t> future<t> submit(runnable task, t result);
future<?> submit(runnable task);

第一个submit方法里面的参数类型就是callable,另外两个本文暂时不涉及。

future和futuretask

future接口的实现类可以对runnable或者callable的任务执行取消、查询、获取结果的操作。

future接口也位于java.util.concurrent包下:

public interface future<t> {
  /**
  *取消任务
  *@param mayinterruptifrunning
  *是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务
  *如果任务正在执行,则返回true
  *如果任务还没有执行,则无论mayinterruptifrunning为true还是false,返回true
  *如果任务已经完成,则无论mayinterruptifrunning为true还是false,返回false
  */
  boolean cancel(boolean mayinterruptifrunning);
  /**
  *任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true
  */
  boolean iscancelled();
  /**
  *任务是否完成
  */
  boolean isdone();
  /**
  *通过阻塞获取执行结果
  */
  t get() throws interruptedexception, executionexception;
  /**
  *通过阻塞获取执行结果。如果在指定的时间内没有返回,则返回null
  */
  t get(long timeout, timeunit unit)
    throws interruptedexception, executionexception, timeoutexception;
}

总结下来future提供了三种功能:

判断任务是否完成
能够中断任务
能够获取任务执行的结果

jdk中为我们提供了一个future接口的实现类futuretask,它有如下两个构造函数。

public futuretask(callable<t> callable) {
}
public futuretask(runnable runnable, t result) {
}

示例代码

使用callable、future

import java.util.concurrent.*;
public class test {
  public static void main(string[] args) {
    executorservice executorservice = executors.newcachedthreadpool();
    task task = new task();
    future<integer> future = executorservice.submit(task);
    executorservice.shutdown();
    
    system.out.println("主线程在执行任务...");
    try {
      thread.sleep(2000);
    } catch(interruptedexception ex) {
      ex.printstacktrace();
    }
     
    try {
      system.out.println("task运行结果:"+future.get());
    } catch (interruptedexception ex) {
      ex.printstacktrace();
    } catch (executionexception ex) {
      ex.printstacktrace();
    } 
    system.out.println("所有任务执行完毕");
  }
}
class task implements callable<integer>{
  @override
  public integer call() throws exception {
    system.out.println("子线程在执行任务...");
    //模拟任务耗时
    thread.sleep(5000);
    return 1000;
  }
}

执行结果:

子线程在执行任务...
主线程在执行任务...
task运行结果:1000
所有任务执行完毕

使用callable、futuretask

import java.util.concurrent.*;
public class test {
  public static void main(string[] args) {
    executorservice executorservice = executors.newcachedthreadpool();
    task task = new task();
    futuretask<integer> futuretask = new futuretask<integer>(task);
    executorservice.submit(futuretask);
    executorservice.shutdown();
    
    system.out.println("主线程在执行任务...");
    try {
      thread.sleep(2000);
    } catch (interruptedexception ex) {
      ex.printstacktrace();
    }
     
    try {
      system.out.println("task运行结果:"+futuretask.get());
    } catch (interruptedexception ex) {
      ex.printstacktrace();
    } catch (executionexception ex) {
      ex.printstacktrace();
    }
     
    system.out.println("所有任务执行完毕");
  }
}
class task implements callable<integer>{
  @override
  public integer call() throws exception {
    system.out.println("子线程在执行任务...");
    //模拟任务耗时
    thread.sleep(5000);
    return 1000;
  }
}

执行结果:

子线程在执行任务...
主线程在执行任务...
task运行结果:1000
所有任务执行完毕

总结

以上就是本文关于浅谈在java中使用callable、future进行并行编程的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!