Журнал LinuxFormat - перейти на главную

LXF87-88:Java

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
м
(Поток, он же thread)
Строка 13: Строка 13:
  
 
=== Поток, он же thread ===
 
=== Поток, он же thread ===
 +
В Java существует два способа работы с потоками: первый заключается в реализации интерфейса Runnable, второй связан с наследованием
 +
класса Thread, который уже реализует данный интерфейс. В обоих случаях класс должен предоставлять реализацию метода run(). Ниже
 +
приведен пример класса, реализующего поток через наследование класса Thread:
 +
<source lang = "java">
 +
public class FirstThread extends Thread {
 +
  public void run(){
 +
    for (int i = 1 ; i < 30; i++)
 +
      System.out.println("It is in thread "+ i);
 +
  }
 +
}
 +
</source>
 +
Собственно, метод run() и должен содержать некоторый набор инструкций (разумеется, на языке Java), которые вы хотите выполнить
 +
в отдельном потоке. Например, если вы реализуете функцию копирования файла (а пользователь, скажем, копирует ISO-образ объемом
 +
600 Мб), желательно, чтобы эта операция выполнялась в отдельном потоке, запуск которого можно производить следующим образом:
 +
<source lang = "java">
 +
public class ConsoleToThread {
 +
  public static void main(String[] args) {
 +
    FirstThread thread = new FirstThread();
 +
    thread.start();
 +
    for (int i = 1; i < 20; i++) {
 +
      System.out.println("It is in main " + i);
 +
    }
 +
    try {
 +
      thread.join();
 +
    }
 +
    catch (InterruptedException ex) {
 +
      System.out.println("Exception in stop thread");
 +
    }
 +
  }
 +
}
 +
</source>
 +
При выполнении метода main() класса ConsoleToThread создается объект-поток FirstThread, который запускается на выполнение методом start() [заметьте – метод run() никогда не вызывается явно, – прим.ред.]. Метод join() используется в случае, когда необходимо «дождаться» завершения потока. Завершение работы потока происходит при выходе из метода run(), как явном (например, посредством return), так и неявном (если внутри метода возникло и не было обработано какое-то исключение).
 +
 +
Имейте в виду (это важно!): повторный запуск уже отработавшего потока приведет к исключению IllegalThreadStateException.
 +
 
=== Реализация потока через Runnable ===
 
=== Реализация потока через Runnable ===
 
=== Приоритеты потоков ===
 
=== Приоритеты потоков ===

Версия 10:32, 17 марта 2008

Содержание

Потоки в Java

ЧАСТЬ 4: Завершая курс молодого Java-бойца, Антон Черноусов научит вас управлять потоками... Жаль, что не денежными.

C каждым днем появляются все более мощные процессоры, многоядерная архитектура которых стала основной темой ушедшего года, поэтому двухядерный процессор в ноутбуке уже никого не удивляет. С одной стороны – это обстоятельство приближает возможности простого пользователя к возможностям «понастоящему» больших систем. С другой (и рекламные буклеты об этом обычно молчат) – для того, чтобы использовать весь потенциал современных компьютеров, приложение должно «уметь» просчитать задачу фактически на двух или более процессорах.

Создание эффективных алгоритмов для работы на многопроцессорных станциях – это большая и сложная работа. Несмотря на это, для любого программиста актуальна задача организации взаимодействия с медленными ресурсами (например, чтения, записи или копирования файлов, работы с принтером, сетью), так как немногие пользователи смирятся с тем, что их любимая программа «замирает» в момент выполнения какой-либо операции.

Во избежание описанных проблем программа должна использовать потоки или процессы. Под процессом понимается заявка на потребле- ние всех видов ресурсов системы, кроме одного – процессорного времени, или иначе говоря, процесс – это запущенная на выполнение программа (такое определение дается в [1]). Поток рассматривается как самостоятельная активность внутри процесса, хотя существуют другие трактовки этого понятия, которые зависят от используемой операционной системы (см., например, [2]). Поток получил свое название по аналогии с потоком команд, поступающих в процессор; при выполнении потоки делят адресное пространство и выделенную память внутри одного процесса. Процессорное время распределяется между различными потоками операционной системой, точнее, одним из компонентов ее ядра – планировщиком. Более полно с понятием процессов и потоков и механизмов работы с ними с точки зрения операционной системы вы можете ознакомиться в книге [3].

Давайте завершим наш экскурс в теорию и окунемся в реальность Java. Под процессом здесь принято понимать всеобъемлющий контекст выполнения, обеспечивающий высокий уровень изоляции охватываемых им данных от внешнего мира, а под потоком – более «легковесный» активный агент; в контексте одного процесса может функционировать целое множество потоков [4]. Планирование потоков в Java обеспечивается внутренними механизмами JVM.

Поток, он же thread

В Java существует два способа работы с потоками: первый заключается в реализации интерфейса Runnable, второй связан с наследованием класса Thread, который уже реализует данный интерфейс. В обоих случаях класс должен предоставлять реализацию метода run(). Ниже приведен пример класса, реализующего поток через наследование класса Thread:

public class FirstThread extends Thread {
  public void run(){
    for (int i = 1 ; i < 30; i++)
      System.out.println("It is in thread "+ i);
  }
}

Собственно, метод run() и должен содержать некоторый набор инструкций (разумеется, на языке Java), которые вы хотите выполнить в отдельном потоке. Например, если вы реализуете функцию копирования файла (а пользователь, скажем, копирует ISO-образ объемом 600 Мб), желательно, чтобы эта операция выполнялась в отдельном потоке, запуск которого можно производить следующим образом:

public class ConsoleToThread {
  public static void main(String[] args) {
    FirstThread thread = new FirstThread();
    thread.start();
    for (int i = 1; i < 20; i++) {
      System.out.println("It is in main " + i);
    }
    try {
      thread.join();
    } 
    catch (InterruptedException ex) {
      System.out.println("Exception in stop thread");
    }
  }
}

При выполнении метода main() класса ConsoleToThread создается объект-поток FirstThread, который запускается на выполнение методом start() [заметьте – метод run() никогда не вызывается явно, – прим.ред.]. Метод join() используется в случае, когда необходимо «дождаться» завершения потока. Завершение работы потока происходит при выходе из метода run(), как явном (например, посредством return), так и неявном (если внутри метода возникло и не было обработано какое-то исключение).

Имейте в виду (это важно!): повторный запуск уже отработавшего потока приведет к исключению IllegalThreadStateException.

Реализация потока через Runnable

Приоритеты потоков

Потоки-демоны

Где искать потоки?

Управление потоками

Мониторы и синхронизация

Взаимные блокировки

Литература

  • 1. П. Кью «Использование UNIX», ISBN 5-8275-0019-4
  • 2. В.Г. Олифер, Н.А. Олифер «Сетевые операционные системы», ISBN 5-272-00120-6
  • 3. Д. Бэкон, Т. Харрис «Операционные системы», ISBN 5-94723-969-8
  • 4. М. Фаулер «Архитектура корпоративных программных приложений», ISBN 5-8459-0579-6
Персональные инструменты
купить
подписаться
Яндекс.Метрика