为什么NewInstance在我的代码中抛出InstantiationException



我有两个过程,如下所示。我的每个过程都有runshutdown方法

Process processA = new ProcessA("processA", getProcessAProperties());
Process processB = new ProcessB("processB", getProcessBProperties());
  • 我想为每个进程具有不同的线程池配置,以便processa在其自己的线程池中运行,而ProcessB则在其自己的线程池中运行,彼此独立。
  • 我无法在其自己的线程池的每个线程之间共享过程对象。

下面是我的过程类的样子,我的ProcessAProcessB类只是扩展过程类。我在运行方法中做所有重要的事情。

public abstract class Process implements Runnable {
  private Properties props;
  private String processName;
  public Process(String processName, Properties props) {
    this.processName = processName;
    this.props = props;
  }
  protected abstract void shutdown();
  protected abstract void run(String processName, Properties props);
  @Override
  public final void run() {
    run(processName, props);
  }
  public Properties getProps() {
    return props;
  }
  public void setProps(Properties props) {
    this.props = props;
  }
  public String getProcessName() {
    return processName;
  }
  public void setProcessName(String processName) {
    this.processName = processName;
  }
}

下面是一个简单的示例,说明了我如何用自己的线程池运行ProcessA有三个线程,每个线程都可以使用自己的processa对象来工作。现在我想以更通用的方式扩展它,以便它可以适用于我的进程ProcessAProcessB

public static void main(String[] args) {
  int numberOfThreads = 3;
  ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
  final List<Process> processes = new ArrayList<>();
  for (int i = 0; i < numberOfThreads; i++) {
    // each thread works on different Process object
    Process processA = new ProcessA("processA", getProcessAProperties());
    processes.add(processA);
    executor.submit(processA);
  }
  Runtime.getRuntime().addShutdownHook(new Thread() {
    @Override
    public void run() {
      for (Process process : processes) {
        process.shutdown();
      } 
      executor.shutdown();
      try {
        executor.awaitTermination(5000, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        e.printStackTrace;
      }
    }
  });
}

因此,要以更通用的方式解决此问题,我创建了一个流程处理程序,如下所示:

public final class ProcessHandler {
  private final ExecutorService executorServiceProcess;
  private final List<Process> processes = new ArrayList<>();
  private final Thread shutdownHook = new Thread() {
    @Override
    public void run() {
      for (Process process : processes)
        process.shutdown();
      executorServiceProcess.shutdown();
    }
  };
  public ProcessHandler(Process process, int poolSize) {
    this.executorServiceProcess = Executors.newFixedThreadPool(poolSize);
    Runtime.getRuntime().addShutdownHook(shutdownHook);
    for (int i = 0; i < poolSize; i++) {
      try {
        // this line throws exception
        Process p = process.getClass().newInstance();
        p.setProcessName(process.getProcessName());
        p.setProps(process.getProps());
        processes.add(p);
        executorServiceProcess.submit(p);
      } catch (InstantiationException | IllegalAccessException e) {
        e.printStackTrace();
      }
    }
  }
  public void shutdown() {
    Runtime.getRuntime().removeShutdownHook(shutdownHook);
    shutdownHook.start();
    try {
      shutdownHook.join();
    } catch (InterruptedException ex) {
      Thread.currentThread().interrupt();
    }
  }
}

这是我的主要方法现在的外观:

public static void main(String[] args) {
    Process processA = new ProcessA("processA", getProcessAProperties());
    Process processB = new ProcessB("processB", getProcessBProperties());
    // processA will run with three threads in its own thread pool
    ProcessHandler processHandlerA = new ProcessHandler (processA, 3);
    // processB will run with two threads in its own thread pool
    ProcessHandler processHandlerB = new ProcessHandler (processB, 2);
    // now I can call shutdown on them
    processHandlerA.shutdown();
    processHandlerB.shutdown();
}

我的ProcessHandlerProcess p = process.getClass().newInstance();中的这一行抛出了例外为:

java.lang.InstantiationException: com.david.test.ProcessA

我不确定为什么要投掷InstantiationException

只需注意:这些过程中的每个过程都是Kafka消费者,通常Kafka消费者不是线程安全的,所以这就是为什么我每次都必须创建一个新对象并提交executor。

更新:

这是我的Processa类看起来:

public class ProcessA extends Process {
  private KafkaConsumer<byte[], byte[]> consumer;
  public ProcessA(String processName, Properties props) {
    super(processName, props);
  }
  @Override
  public void shutdown() {
    consumer.wakeup();
  }
  @Override
  protected void run(String processName, Properties props) {
    consumer = new KafkaConsumer<>(props);
    System.out.println("Hello World");
    // do all kind of important stuff here
  }
}

您是一个延长过程抽象类的具体类吗?

摘要类无法自行实例化,请参阅:http://docs.oracle.com/javase/tutorial/java/java/iandi/abstract.html

也许尝试使用混凝土类扩展抽象类并创建具体类的实例,如果需要,您仍然可以将它们作为过程对象。

processa中的构造函数

 public ProcessA(String processName, Properties props);

因此,不存在任何毫无根据的构造函数:

 public ProcessA();

 Process p = process.getClass().newInstance()

将调用一种不存在的无肢体构造方法,因此将出现例外。

有关更多信息,请查看https://docs.oracle.com/javase/tutorial/reflect/member/member/ctorinstance.html。

相关内容

  • 没有找到相关文章

最新更新