Пример #1
0
  /** {@inheritDoc} */
  @Override
  public void run() {
    while (!this.isShutdown) {

      // handle "everything is empty"
      this.addLock.lock();
      try {
        // sleep if there is nothing to do
        while (this.pool.size() + this.queue.size() + this.add.size() + this.addQueue.size() == 0) {
          if (this.threadIsEmpty.awaitNanos(TimeUnit.MINUTES.toNanos(2)) <= 0 || this.isShutdown) {
            this.isShutdown = true;
            this.pool.clear();
            return;
          }
        }
        this.pool.addAll(this.add);
        this.add.clear();
        this.queue.addAll(this.addQueue);
        this.addQueue.clear();
      } catch (InterruptedException e) {
        this.isShutdown = true;
        this.pool.clear();
        this.queue.clear();
        return;
      } finally {
        this.addLock.unlock();
      }

      // remove jobs on request
      this.removeLock.lock();
      try {
        this.pool.removeAll(this.remove);
        Iterator<Entry> iter = this.queue.iterator();
        while (iter.hasNext()) if (this.remove.contains(iter.next().job)) iter.remove();
        this.remove.clear();
      } finally {
        this.removeLock.unlock();
      }

      // first handle normal jobs
      Iterator<IDoJob> poolIT = this.pool.iterator();
      while (poolIT.hasNext()) {
        IDoJob job = poolIT.next();
        if (!job.isfinished())
          try {
            job.doJob();
          } catch (Exception e) {
            LOGGER.severe(
                "The job " + job.name() + " threw an exception and has been subsequently removed.",
                e);
            poolIT.remove();
            this._shutdownJob(job);
          }
        else poolIT.remove();
      }

      if (!this.queue.isEmpty()) {
        final long ctime = Platform.currentTime();
        // first work on jobs that are overdue
        Iterator<Entry> queueIT = this.queue.iterator();
        while (queueIT.hasNext()) {
          Entry entry = queueIT.next();
          if (entry.time > ctime) break;
          queueIT.remove();
          if (!entry.job.isfinished()) {
            try {

              if (entry.loop != Entry.NO_LOOP) {
                entry.job.doJob();
                entry.time = Math.max(entry.time + entry.loop, ctime);
                entry._decipher = Entry.DECIPHER++;
                this.addLock.lock();
                try {
                  this.addQueue.add(entry);
                } finally {
                  this.addLock.unlock();
                }
              } else this.addJob(entry.job);
            } catch (Exception e) {
              LOGGER.severe(
                  "The job "
                      + entry.job.name()
                      + " threw an exception and has been subsequently removed.",
                  e);
              this._shutdownJob(entry.job);
            }
          }
        }
      }
      this.addLock.lock();
      try {
        long time = 0;
        // we need to sleep when there are jobs in the queue that should not be worked on yet, but
        // there are no jobs in the pool
        while (this.pool.size() + this.add.size() + this.addQueue.size() == 0
            && !this.queue.isEmpty()
            && (time = this.queue.peek().time - Platform.currentTime()) > 5) {
          this.threadIsEmpty.await(time, TimeUnit.MILLISECONDS);
        }
      } catch (InterruptedException e) {
        // do nothing just check the conditions above
      } finally {
        this.addLock.unlock();
      }
    }
    for (IDoJob job : this.pool) this._shutdownJob(job);
    for (Entry entry : this.queue) this._shutdownJob(entry.job);
    this.pool.clear();
    this.queue.clear();
  }