/*
* Encog(tm) Core v3.4 - Java Version
* http://www.heatonresearch.com/encog/
* https://github.com/encog/encog-java-core
* Copyright 2008-2016 Heaton Research, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information on Heaton Research copyrights, licenses
* and trademarks visit:
* http://www.heatonresearch.com/copyright
*/
package org.encog.util.concurrency.job;
import org.encog.StatusReportable;
import org.encog.util.concurrency.EngineConcurrency;
import org.encog.util.concurrency.MultiThreadable;
import org.encog.util.concurrency.TaskGroup;
/**
* This class forms the basis for a job that can be run concurrently.
*/
public abstract class ConcurrentJob implements Runnable, MultiThreadable {
/**
* The thread count.
*/
private int threadCount;
/**
* The class to report status to.
*/
private StatusReportable report;
/**
* The number of tasks in this job.
*/
private int totalTasks;
/**
* The current task.
*/
private int current;
/**
* Flag to note that the job should stop.
*/
private boolean shouldStop = false;
/**
* Is the job running.
*/
private boolean running;
/**
* Construct a concurrent job.
*
* @param report
* The object to report status to.
*/
public ConcurrentJob(final StatusReportable report) {
this.report = report;
this.current = 1;
}
/**
* Load the subtasks.
*
* @return The total number of subtasks.
*/
public abstract int loadWorkload();
/**
* Perform one job unit.
*
* @param context
* The context for the job unit.
*/
public abstract void performJobUnit(JobUnitContext context);
/**
* Process the job.
*/
public void process() {
Object task;
EngineConcurrency.getInstance().setThreadCount(this.threadCount);
this.running = true;
this.totalTasks = loadWorkload();
int currentTask = 0;
TaskGroup group = EngineConcurrency.getInstance().createTaskGroup();
while (((task = requestNextTask()) != null) && !shouldStop) {
currentTask++;
final JobUnitContext context = new JobUnitContext();
context.setJobUnit(task);
context.setOwner(this);
context.setTaskNumber(currentTask);
final JobUnitWorker worker = new JobUnitWorker(context);
EngineConcurrency.getInstance().processTask(worker, group);
}
group.waitForComplete();
this.running = false;
EngineConcurrency.getInstance().checkError();
}
public void processBackground() {
Thread t = new Thread(this);
t.start();
}
/**
* Report the status for this job.
*
* @param context
* The job context.
* @param status
* The status to report.
*/
public void reportStatus(final JobUnitContext context,
final String status) {
this.report.report(this.totalTasks, current++, status);
}
/**
* Request the next task to be processed.
*
* @return The next task to be processed.
*/
public abstract Object requestNextTask();
/**
* @return True if the process should stop.
*/
public boolean getShouldStop() {
return this.shouldStop;
}
/**
* Request the process to stop.
*/
public void stop() {
this.shouldStop = true;
}
public void run() {
process();
}
/**
* @return the running
*/
public boolean isRunning() {
return running;
}
public void setReport(StatusReportable r) {
this.report = r;
}
/**
* {@inheritDoc}
*/
public int getThreadCount()
{
return this.threadCount;
}
/**
* {@inheritDoc}
*/
public void setThreadCount(int numThreads)
{
this.threadCount = numThreads;
}
}