Понедельник, 06.01.2025
Приветствую Вас Гость

Шенденков С.В.
(Zmey)

Если Вы хотите вернуться на предыдущий язык, то нажмите кнопку Назад в Вашем браузере
Выбрать язык / Choose language:
Ukranian
English
French
German
Japanese
Italian
Portuguese
Spanish
Danish
Chinese
Korean
Arabic
Czech
Estonian
Belarusian
Latvian
Greek
Finnish
Serbian
Bulgarian
Turkish
Главная | Регистрация | Вход | RSS

Многопоточность в Java

Как известно современная компьютер позволяет работать нескольким программам одновременно. На самом деле это не всегда правда. Дело в том, что любая операция происходит в процессоре. Код программ выполняет центральный процессор, а точнее его АЛУ (арифметико-логическое устройство). АЛУ + кэш-память составляет ядро процессора. В один момент времени на одном ядре может выполняться только одна инструкция. Пользователю компьютера кажется что несколько программ работает одновременно только потому, что процессор быстро выполняет подаваемые ему инструкции, а операционная система быстро переключается между программами и передаёт эти инструкции на процессор.
Самая простая программа состоит из одного потока, но современным программам этого недостаточно. Если необходимо, чтобы программа псевдо-одновременно следила за несколькими воздействиями, выполняла несколько псевдо-паралельных операций и т.д., то нам не обойтись без создания многопоточности в нашей программе. Каждый поток в программе фактически является небольшой программкой, которая работает независимо. Для того чтобы объединить и скоординировать все работающие в программе потоки необходимо разрабатывать координирующий поток или систему общения между потоками.
Приступим к практике. Создайте новый проект, назовите его например Zmey_Console_Threads_Example. Автоматически созданный основной класс Main мы будем использовать как координирующий поток. Приведём его вид к следующему:

package zmey_console_threads_example;

/**
 *
 * @author Zmey
 * @author http://shendenkov.at.ua
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Флаги для остановки потоков
        boolean stoped_a = false;
        boolean stoped_b = false;
        boolean stoped_c = false;
        // Создаём потоки
        Thread_A a = new Thread_A();
        Thread_B b = new Thread_B();
        Thread_C c = new Thread_C();
        // Начальное время в миллисекундах
        long starting_time = System.currentTimeMillis();
        // Старт потоков
        a.start();
        b.start();
        c.start();
        // Пока хоть один из потоков работает
        while (a.isAlive() || b.isAlive() || c.isAlive()) {
            // Если с начального времени прошло 60 секунд
            if (starting_time + 60000 < System.currentTimeMillis()
                    && !stoped_a) {
                a.exit();
                stoped_a = true;
                System.out.println("stoping Thread A");
            }
            // Если с начального времени прошло 120 секунд
            if (starting_time + 120000 < System.currentTimeMillis()
                    && !stoped_b) {
                b.exit();
                stoped_b = true;
                System.out.println("stoping Thread B");
            }
            // Если с начального времени прошло 180 секунд
            if (starting_time + 180000 < System.currentTimeMillis()
                    && !stoped_c) {
                c.exit();
                stoped_c = true;
                System.out.println("stoping Thread C");
            }
        }
    }

}

Далее создадим ещё три класса в том же пакете. Каждый класса будем наследовать от класса потока (Thread) используя ключевое слово extends.
 
Поток A:

package zmey_console_threads_example;

/**
 *
 * @author Zmey
 * @author http://shendenkov.at.ua
 */
public class Thread_A extends Thread {

    public boolean working = true;

    @Override
    public void run() {
        // Начальное знаение счётчика
        int i = 1000;
        // Пока поток должен работать
        while (working) {
            try {
                System.out.println("Thread A sleep " + i 
                        + " miliseconds");
                // Пауза на указанное количество миллисекунд
                sleep(i);
                // Добавляем 10. Это выражение равнозначно i = i + 10
                i += 10;
            } catch (InterruptedException ex) {
            }
        }
    }

    public void exit() {
        working = false;
    }
}

Поток B:

package zmey_console_threads_example;

/**
 *
 * @author Zmey
 * @author http://shendenkov.at.ua
 */
public class Thread_B extends Thread {

    public boolean working = true;

    @Override
    public void run() {
        int i = 2000;
        while (working) {
            try {
                System.out.println("Thread B sleep " + i 
                        + " miliseconds");
                sleep(i);
                i += 20;
            } catch (InterruptedException ex) {
            }
        }
    }

    public void exit() {
        working = false;
    }
}

Поток C:

package zmey_console_threads_example;

/**
 *
 * @author Zmey
 * @author http://shendenkov.at.ua
 */
public class Thread_C extends Thread {

    public boolean working = true;

    @Override
    public void run() {
        int i = 3000;
        while (working) {
            try {
                System.out.println("Thread C sleep " + i 
                        + " miliseconds");
                sleep(i);
                i += 30;
            } catch (InterruptedException ex) {
            }
        }
    }

    public void exit() {
        working = false;
    }
}

Как мы можем видеть, классы-потоки, которые мы создали, очень похожи друг на друга. Разница только в счётчике, который мы используем для паузы потока. Это создано для примера, на практике один поток может обрабатывать сетевые коммуникации, другой поток работать с базой данных и т.д.
Давайте разберёмся, что выполняет каждый поток.
Классы потоков A, B и C наследуются от класса Thread, который заставляет нас создать метод run в каждом из них. Для того чтобы поток начал свою работу его мало создать (для этого используется конструктор), его ещё и необходимо запустить (для этого используется метод start суперкласса - Thread). Само выполнение потока происходит в методе run.
После старта поток инициализирует счётчик и входит в условный цикл while. В цикле поток выводит на консоль сообщение. Это и есть "полезная работа" в нашем потоке. Затем поток уходит в паузу на указанное количество миллисекунд и изменяем счётчик. Выход из цикла, а значит и окончание работы потока, произойдёт только тогда когда переменная working измениться на false.
В координирующем потоке Main мы создаём три потока, замеряем время перед стартом, стартуем потоки и входим в цикл слежения за их состоянием. Пока работает хоть один из наших потоков и будет работать координирующий поток. Мы с Вами отвели на работу потока A 1 минуту, на работу потока B - 2 минуты и на работу потока C - 3 минуты. Для того чтобы остановить поток я рекомендую использовать логическую переменную working, потому что метод interrupt, который предполагался для того, чтобы прерывать и останавливать поток, к сожалению, не работает. Поэтому единственный способ корректно остановит поток это дать ему завершиться самостоятельно. Если время, которое должен выполняться поток неизвестно, то его можно остановить выйдя из условного цикла.
Запустите программу в NetBeans или консоли и понаблюдайте за её действиями в течении 3 минут. Вы должны увидеть что действия каждого из потоков являются независимыми. Можете поэкспериментировать с разными временными промежутками. Вот мы и научились создавать, запускать и останавливать потоки в Java.


Нравится


Гость
Сообщения:

Гость, мы рады Вас видеть.
Пожалуйста зарегистрируйтесь или войдите под своим логином.
Поиск
«  Январь 2025  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031
Содержание
Наш опрос
Кто производитель Вашего мобильного телефона?

Результаты Архив опросов


Всего голосовало: 62
Обсудить опрос на форуме
Друзья сайта
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
free counters



Каталог сайтов Нашли.com - тематический каталог сайтов, поиск Каталог сайтов - Первый в WWW