Example #1
0
  /**
   * The method being executes when the status of the workContainer is RUNNABLE. There is no check
   * whether or not the status is runnable before executing this method, so checking if the status
   * is actually RUNNABLE is a good check.
   */
  @Override
  public void run() {
    // If it isn't runnable, it should't run. (Never happened besides from aborted jobs).
    if (status.getStatus() != Status.RUNNABLE) {
      // If it was just aborted, then we just quit, say nothing about it.
      if (status.getStatus() != Status.ABORTED) {
        // Hasn't happened yet. If it does, then that is very very bad!
        throw new RuntimeException(
            "The workContainer was told to work, although its status is currently " + status);
      }
      return;
    }

    resetSubJobId();
    subJobsCommitted = false;

    // Running the thing is easy, it should be.
    // work() and join() gets treated completely the same. Only difference being if earlier jobs are
    // passed on.
    E result;
    if (results == null) {
      result = job.work(scheduler);
    } else {
      result = job.join(results, scheduler);
    }
    if (!subJobsCommitted) {
      // We just need to submit an result.
      this.result = result;
      // I'm only submitting the result, if i can change the status to HAS_RESULT. And it is
      // synchronized because i changes the state of the object.
      synchronized (this) {
        if (status.setStatus(Status.HAS_RESULT)) {
          env.submitResult(this);
        }
      }
    } else {
      subJobLock.lock();
      try {
        // This is if all the results have already gotten back, since that happens multithreaded,
        // that can happen.
        if (missingJobs.size() == 0) {
          runAgain(); // Not running it again right now, just putting it in the queue.
        } else {
          status.setStatus(Status.NEED_RESULTS); // Waiting.
        }
      } finally {
        subJobLock.unlock();
      }
    }
  }
Example #2
0
  /**
   * Submits a result that this workcontainer has been waiting for. This method is thread safe.
   *
   * @param id of the job. (The ID thats only unique inside this workcontainer).
   * @param result
   */
  public void putResult(int id, E result) {
    subJobLock.lock();
    try {
      // Making the list if it isn't there.
      if (results == null) {
        results = new ArrayList<E>();
      }
      // Expanding it if we need more room.
      while (id >= results.size()) {
        results.add(null);
      }

      Integer key = new Integer(id);
      if (missingJobs.containsKey(key)) {
        missingJobs.remove(key);
        results.set(id, result);
        // Everything that is a state change of this object, is synchronized to the object.
        synchronized (this) {
          if (missingJobs.size() == 0 && status.getStatus() == Status.NEED_RESULTS) {
            runAgain();
          }
        }
      }
    } finally {
      subJobLock.unlock();
    }
  }
Example #3
0
  /**
   * This method is called when all subJobs have been completed, and we need to put this job back in
   * the jobQueue.
   */
  private void runAgain() {
    // Only putting it in, if i'm able to change the status to RUNNABLE.
    synchronized (this) {
      if (status.setStatus(Status.RUNNABLE)) {
        try {
          env.putJobInQueue(this);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        }
      } else {
        System.out.println("Not running again, i couldn't set the status to Runnable");
      }

      // In any case, removing it from the idle jobs.
      env.removeIdleJob(this.getId());
    }
  }
Example #4
0
 /**
  * Hold the result when it is ready, if there is no result ready, it will throw an
  * RuntimeException.
  *
  * @return the result calculated by the job this WorkContainer contains.
  */
 public E getResult() {
   if (status.getStatus() != Status.HAS_RESULT)
     System.out.println("Status is " + status + ", but yet someone accessed the result. ");
   return result;
 }
Example #5
0
 /**
  * Returns the current status of this job, if it is RUNNABLE, NEED_RESULTS or HAS_RESULTS.
  *
  * @return current status of this job.
  */
 public Status getStatus() {
   return status.getStatus();
 }