Mutual exclusion
One way to do it would be using a locking object, a mutex, shared between your processing classes.
public static void main(String[] args) {
ProcessingMutex mutex = new ProcessingMutex();
Processor fileProcessorOne = new ProcessorOne(mutex);
Processor fileProcessorTwo = new ProcessorTwo(mutex);
// start threads and do your stuff
}
The mutex object would contain some logic to prevent one thread overriding the other threads lock:
public class ProcessingMutex {
private Object processor = null;
public boolean processing() {
return processor != null;
}
public synchronized void start(Object p) {
if (processor == null) {
processor = p;
} else {
throw new IllegalStateException("Already processing!");
}
}
public synchronized void finished(Object p) {
if (processor == p) {
processor = null;
} else {
// Optional: throw new IllegalStateException("Cannot reset other processors flag!");
}
}
}
Since they share the locking mechanism I derived the two processor classes from the same parent which implements the locking:
public abstract class Processor /* extends Runnable? */ {
private final ProcessingMutex mutex;
public Processor(ProcessingMutex mutex) {
this.mutex = mutex;
}
public void processFile() {
if (getLock()) {
try {
doProcess();
} finally {
// make sure to release lock -> finally
releaseLock();
}
}
}
protected abstract void doProcess();
private boolean getLock() {
// query and set mutex in synchronized block to prevent interference with other thread
synchronized (mutex) {
if (!mutex.processing()) {
mutex.start(this);
}
}
return false;
}
private void releaseLock() {
mutex.finished(this);
}
}
public class ProcessorOne extends Processor {
public ProcessorOne(ProcessingMutex mutex) {
super(mutex);
}
@Override
protected void doProcess() {
// TODO add file processing algorithm one
}
}
public class ProcessorTwo extends Processor {
public ProcessorTwo(ProcessingMutex mutex) {
super(mutex);
}
@Override
protected void doProcess() {
// TODO add file processing algorithm two
}
}
Disclaimer:
Please note, that this is only a very basic (late night) version to demonstrate my thoughts. It's has to be hardened in matters of thread-safety depending on the needs of your application.
Edit:
java.util.concurrent
You could of course use one of the Lock objects provided by Java (see java.util.concurrent API doc) as suggested in this other answer: https://stackoverflow.com/a/3493788/4791599