在静态块中使用ExecutorService提交Callable

时间:2018-08-03 02:50:47

标签: executorservice callable static-block

在使用ExecutorService在静态块中执行Callable时遇到一个奇怪的问题。让我们直接在下面看到完整的代码。

package com.acme;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class App {
   private static int data = 0;

   static {
       ExecutorService executor = Executors.newFixedThreadPool(1);
       Future<String> future = executor.submit(new Callable<String>() {
           @Override
           public String call() throws Exception {
               System.out.println("" + data);
               return "hello";
           }
       });       
     }

  public static void main(String[] args) {
    System.out.println("enter main scope");
  }
 }

运行main方法,结果如下图所示。

enter image description here

但是,如果我添加以下一些业务代码,则控制台中不会打印任何内容。

 public class App {
   private static int data = 0;

   static {
       ExecutorService executor = Executors.newFixedThreadPool(1);
       Future<String> future = executor.submit(new Callable<String>() {
           @Override
           public String call() throws Exception {
               System.out.println("" + data);
               return "hello";
           }
       });    

      try {
          future.get();
      } catch (InterruptedException e) {
          e.printStackTrace();
      } catch (ExecutionException e) {
          e.printStackTrace();
      }   
  }

  public static void main(String[] args) {
    System.out.println("enter main scope");
  }
 }

任何人都可以提供有关此问题的帮助吗?更多细节。

1 个答案:

答案 0 :(得分:0)

当您使执行程序代码在静态块中运行时,这甚至迫使代码甚至在App.class上下文完全创建之前就运行了(即,类未完全加载到内存中,或者您现在可以说“ data”变量不在内存中)。

基本上,当您的调用方法通过执行程序被调用时,它的(线程)试图在App.class中找到变量“ data”,但直到现在可能尚未加载,这也使线程无限运行。

解决方案:

  1. 在主块中运行执行程序,但仍然存在问题,假设如果由于某种原因(业务逻辑)卸载了App.class,您将再次陷入无限运行的线程中,该线程正在查找“数据”

  2. 使数据变量为“ final”,然后您可以将代码放置为静态块或静态方法(例如main)。至于最终变量,将保留一个单独的副本,并且不会出现类加载或卸载的问题。