Пример #1
0
 @Override
 public void submit() {
   //            final FibersMonitor monitor = fiber.getMonitor();
   //            if (monitor != null & fiber.getState() != Strand.State.STARTED)
   //                monitor.fiberResumed();
   if (getPool() == fjPool) fork();
   else fjPool.submit(this);
 }
  /**
   * Process all elements from the {@code failedToProcess} and then {@code things} concurrently in
   * the underlying pool. Processing happens concurrently maintaining {@code
   * JobSchedulerImpl.CORES_COUNT} parallelism. Stop when {@code tombStone} element is occurred. If
   * was unable to process some element, add it back to the {@code failedToProcess} queue.
   *
   * @return true if all elements processed successfully, false if at least one processor returned
   *     false or exception occurred
   */
  public <T> boolean processQueue(
      @NotNull final BlockingQueue<T> things,
      @NotNull final Queue<T> failedToProcess,
      @NotNull final ProgressIndicator progress,
      @NotNull final T tombStone,
      @NotNull final Processor<? super T> thingProcessor) {
    class MyTask implements Callable<Boolean> {
      private final int mySeq;
      private boolean result;

      private MyTask(int seq) {
        mySeq = seq;
      }

      @Override
      public Boolean call() throws Exception {
        ProgressManager.getInstance()
            .executeProcessUnderProgress(
                () -> {
                  try {
                    while (true) {
                      progress.checkCanceled();
                      T element = failedToProcess.poll();
                      if (element == null) element = things.take();

                      if (element == tombStone) {
                        things.offer(element);
                        result = true;
                        break;
                      }
                      try {
                        if (!thingProcessor.process(element)) {
                          result = false;
                          break;
                        }
                      } catch (RuntimeException e) {
                        failedToProcess.add(element);
                        throw e;
                      }
                    }
                  } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                  }
                },
                progress);
        return result;
      }

      @Override
      public String toString() {
        return super.toString() + " seq=" + mySeq;
      }
    }

    boolean isSmallEnough = things.contains(tombStone);
    if (isSmallEnough) {
      try {
        // do not distribute for small queues
        return new MyTask(0).call();
      } catch (RuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }

    List<ForkJoinTask<Boolean>> tasks = new ArrayList<>();
    for (int i = 0; i < JobSchedulerImpl.CORES_COUNT; i++) {
      tasks.add(pool.submit(new MyTask(i)));
    }

    boolean result = true;
    RuntimeException exception = null;
    for (ForkJoinTask<Boolean> task : tasks) {
      try {
        result &= task.join();
      } catch (RuntimeException e) {
        exception = e;
      }
    }
    if (exception != null) {
      throw exception;
    }
    return result;
  }
 private void submit() {
   pool.submit(myForkJoinTask);
 }