* public InputStream getInputStream() – дает возможность получать поток ввода процесса;
* getErrorStream(), getOutputStream() – методы, аналогичные getInputStream(), но получающие, соответственно, стандартные потоки сообщений об ошибках и вывода;
* public void destroy() – уничтожает процесс; все подпроцессы, запущенные из него, также будут уничтожены;
* public int exitValue() – возвращает код завершения процесса; по соглашению, код завершения, равный 0, означает нормальное завершение;
* public int waitFor() – вынуждает текущий поток выполнения приостановиться до тех пор, пока не будет завершен процесс, представленный этим экземпляром Process; возвращает значение кода завершения процесса.
Даже если в приложении Java не будет ни одной ссылки на объект Process, процесс не будет уничтожен и будет продолжать асинхронно выполняться до своего завершения. Спецификацией не оговаривается механизм, с помощью которого будет выделяться процессорное время на выполнение процессов Process и потоков Java. Поэтому при проектировании программ не стоит полагаться ни на какой из них, так как различные Java-машины могут демонстрировать различное поведение.
Потоки исполнения
Многопоточная архитектура в Java была подробно рассмотрена в лекции 12. Остановимся более подробно на методах применяемых классов.
Runnable
Runnable – это интерфейс, содержащий один-единственный метод без параметров: run().
Thread
Объекты этого класса представляют возможность запускать и управлять потоками исполнения.
Итак, для управления потоками в классе Thread предусмотрены следующие методы:
* public void start() – производит запуск нового потока;
* public final void join() – если поток A вызывает этот метод у объекта Thread, представляющего поток B ( threadB.join() ), то выполнение потока A приостанавливается до тех пор, пока не закончит выполнение поток B ;
* public static void yield() – поток, из которого вызван этот метод, временно приостанавливается, чтобы дать возможность выполняться другим потокам;
public static void sleep(long millis) – поток, из которого вызван этот метод, перейдет в состояние "сна" на указанное количество миллисекунд, после чего сможет продолжить выполнение. При этом нужно учесть, что через время millis миллисекунд этому потоку может быть выделено процессорное время, а может, ему придется и подождать немного дольше. Можно сказать, что поток продолжит выполнение не раньше, чем через время millis миллисекунд.
Существует еще несколько методов, которые объявлены deprecated и рекомендуется их избегать. Это: suspend() – временно прекратить выполнение, resume() – продолжить выполнение (приостановленное вызовом suspend()), stop() – остановить выполнение потока.
При вызове метода stop() в потоке, который представляет этот объект Thread, будет брошена ошибка ThreadDeath. Этот класс унаследован от Error. Если ошибка не будет обработана в программе и, соответственно, произойдет прекращение работы потока, сообщение о ненормальном завершении выведено не будет, так как такое завершение рассматривается как нормальное. Если же в программе эта ошибка обрабатывается (например, для проведения каких-то дополнительных действий перед закрытием потока), то очень важно позаботиться о том, чтобы эта же ошибка была брошена дальше, чтобы поток действительно закончил свое выполнение. Класс ThreadDeath специально унаследован от Error, а не от Exception, так как очень часто используется перехват всех исключений класса Exception, что не позволит корректно остановить поток.
Также Thread позволяет выставлять такие свойства потока, как:
* Name – значение типа String, которое можно использовать для более наглядного обращения с потоками в группе;
* Daemon – выполнение программы не будет прекращено до тех пор, пока выполняется хотя бы один не daemon поток;
* Priority – определяет приоритет потока. В классе Thread определены константы, задающие минимальное и максимальное значения для приоритетов потока,– MIN_PRIORITY и MAX_PRIORITY, а также значение приоритета по умолчанию – NORM_PRIORITY.
Эти свойства могут быть изменены только до того момента, когда поток будет запущен, то есть вызван метод start() объекта Thread.
Получить эти значения можно, конечно же, в любой момент жизни потока – и после его запуска, и после прекращения выполнения. Также можно узнать, в каком состоянии сейчас находится поток: вызовом методов isAlive() – выполняется ли еще, isInterrupted() – прерван ли.
ThreadGroup
Для того, чтобы отдельный поток не мог начать останавливать и прерывать все потоки подряд, введено понятие группы. Поток может оказывать влияние только на потоки, которые находятся в одной с ним группе. Группу потоков представляет класс ThreadGroup. Такая организация позволяет защитить потоки от нежелательного внешнего воздействия. Группа потоков может содержать другие группы, что позволяет организовать все потоки и группы в иерархическое дерево, в котором каждый объект ThreadGroup, за исключением корневого, имеет родителя.
Читать дальше