Более общо:
Учитывая экземпляр х Callable использования глобальных переменных A и B, как я могу запустить х одновременно такие, что х видит собственные значения А и В, а не «оригинальных» значений A и B?
И лучший ответ: не используйте глобальные переменные. Зависимость вводит такие вещи. Расширьте Callable и добавьте методы setStdIn, setStdOut (и setStdErr, если вам это нужно).
Я знаю, что это не тот ответ, который вы ищете, но решения, которые я видел для этого, требуют нового процесса, и единственный способ, которым вы получаете этот Callable в новый процесс, - это изменить код Callable, так что он сериализуется или предоставляет имя класса или какой-либо другой хак, поэтому вместо внесения изменений, которые дадут вам неприятное, хрупкое решение, просто сделайте это правильно *
* «Право» использовать широко распространенная схема инъекции зависимостей для обеспечения рыхлой связи. YMMV
UPDATE: В ответ на комментарий 1. Вот ваш новый интерфейс:
import java.io.InputStream;
import java.io.PrintStream;
import java.util.concurrent.Callable;
public interface MyCallable<V> extends Callable<V> {
void setStdIn(InputStream in);
void setStdOut(PrintStream out);
}
и ваши задачи будет выглядеть следующим образом:
import java.io.InputStream;
import java.io.PrintStream;
public class CallableTask implements MyCallable<Object> {
private InputStream in = System.in;
private PrintStream out = System.out;
public void setStdIn(InputStream in) {
this.in = in;
}
public void setStdOut(PrintStream out) {
this.out = out;
}
public Object call() throws Exception {
out.write(in.read());
return null;
}
}
Нет необходимости в процессе , Любое решение (даже одно из процессов) почти наверняка потребует изменения кода в Callables в некотором роде. Это самый простой (просто замените System.out на this.out).
ProcessBuilder, AFAICT, хочет строку командной строки, а не вызываемую. Я определенно хочу вызвать экземпляр и не создавать новый экземпляр на основе имени класса. Что касается процесса vs. thread, см. Выше. – 2008-12-04 23:43:26
Я имел в виду, что вы даете java.exe как команду ProcessBUilder, а для основного класса вы даете оболочку, которая запускает вызываемый. Конечно, вам нужно будет сериализовать экземпляр и передать имя файла в качестве параметра в ваш основной класс. Или просто используйте System.setIn()/out() и т. Д. – Yoni 2008-12-06 03:45:36