Skip to content

Callable和线程池

Callable接口jdk5+

Callable<V> 接口用于表示可以在单独线程中执行并返回结果的任务。

Callable 与 Runnable 类似,但有以下几个区别:

  1. 返回结果:Callable 的 call() 方法可以返回结果,而 Runnable 的 run() 方法返回 void;

  2. 抛出异常:Callable 的 call() 方法可以通过 throws 抛出异常,而 Runnable 的 run() 方法只能 try..catch..;

缺点

  1. 在主线程中调用 get() 方法获取 call() 方法的返回值时,会堵塞主线程
java
public static void main(String[] args) {
  MyThread myThread = new MyThread();
  FutureTask<Integer> futureTask = new FutureTask<>(myThread);

  Thread thread = new Thread(futureTask);
  thread.start();

  try {
    //调用该方法时,主线程是阻塞状态,也就是 myThread 线程执行完毕,才会执行这句
    Integer res = futureTask.get();
    System.out.println("总和是:" + res);
  } catch (Exception e) {
    e.printStackTrace();
  }
}

class MyThread implements Callable<Integer> {
  @Override
  public Integer call() throws Exception {
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
      if (i % 2 == 0) {
        System.out.println(i);
        sum += i;
      }
    }
    return sum;
  }
}
java
public static void main(String[] args) {
  //提供指定线程数量的线程池
  ExecutorService service = Executors.newFixedThreadPool(10);
  //实现 Callable 接口时,使用 submit() 调用
  service.submit(new MyThread());
  //关闭线程池
  service.shutdown();
}

线程池JUC深入讲解

线程池的优势:

  1. 提高了程序执行的效率:因为线程池已经提前创建好了;
  2. 提高了资源复用率:因为执行完的线程并没有立即销毁,而是可以继续执行其他的任务;
  3. 可以设置线程的相关参数:对线程池中的使用进行管理;
java
public static void main(String[] args) {
  //提供指定线程数量的线程池
  ExecutorService service = Executors.newFixedThreadPool(10);
  ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;

  //设置线程池中线程数的上限
  service1.setMaximumPoolSize(50);

  //实现 Runnable 接口,使用 execute() 方法调用
  service.execute(new PrintfEven());
  service.execute(new PrintfOdd());

  //关闭连接池
  service.shutdown();
}

class PrintfEven implements Runnable {
  @Override
  public void run() {
    for (int i = 1; i <= 100; i++) {
      if (i % 2 == 0) {
        System.out.println("线程一:" + i);
      }
    }
  }
}

class PrintfOdd implements Runnable {
  @Override
  public void run() {
    for (int i = 1; i <= 100; i++) {
      if (i % 2 != 0) {
        System.out.println("线程二:" + i);
      }
    }
  }
}

Released under the MIT License.