Руководство по Java Core. Многопоточность. Взаимодействие потоков.

В реальных приложениях мы часто сталкиваемся с ситуацией, когда два потока обмениваются какой-либо информацией.

Для обеспечения этого процесса применяются такие методы, как

  • public void wait()
    Этот  метод переводит поток в режим ожидания до момента вызова метода notify().
  • public void notify()
    Этот метод переводит один поток из режима ожидания в активный режим.
  • public void notifyAll()
    Этот метод переводит все потоки, которые находятся в режиме ожидания в активный режим.

Все эти методы реализованы, как финальные методы класса Object, что означает их доступность для любого класса в языке программирования Java. Все эти методы могут быть применены только в контексте синхронизации.

Для понимания того, как это работает на практике, рассмотрим пример простого приложения.

Пример:

Класс ThreadsInteraction


public class ThreadInteraction {
    boolean isActive = false;

    public synchronized void Request(String request){
        if(isActive){
            try {
                wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        System.out.println("Pilot:");
        System.out.println(request);
        isActive = true;
        notify();
    }

    public synchronized void Response(String response){
        if(!isActive){
            try {
                wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }

        System.out.println("Controller:");
        System.out.println(response);
        isActive = false;
        notify();
    }
}

Класс Request


public class Request implements Runnable {
    ThreadInteraction interaction;
    String[] request =
            {
                    "Dnipro Radar, Aeroflot 1816",
                    "Request descent, Aeroflot 1816",
                    "Descending to altitude 6,000 feet, Aeroflot 1816"
            };

    public Request(ThreadInteraction interaction) {
        this.interaction = interaction;
        new Thread(this, "Request").start();
    }

    @Override
    public void run() {
        for (int i = 0; i < request.length; i++) {
            interaction.Request(request[i]);
        }
    }
}

Класс Response


public class Response implements Runnable {
    ThreadInteraction interaction;
    String[] response =
            {
                    "Aeroflot 1816, Dnipro Radar, go ahead",
                    "Aeroflot 1816, descend to altitude 6,000 feet"
            };

    public Response(ThreadInteraction interaction) {
        this.interaction = interaction;
        new Thread(this, "Response").start();
    }

    @Override
    public void run() {
        for (int i = 0; i < response.length; i++) {
            interaction.Response(response[i]);
        }
    }
}

Класс ThreadsInteractionDemo


public class ThreadInterActionDemo {
    public static void main(String[] args) {
        ThreadInteraction interaction = new ThreadInteraction();

        Request request = new Request(interaction);
        Response response = new Response(interaction);
    }
}

В результате работы этой программы, мы получим, примерно, следующий результат:


/*Some System Messages*/

Pilot:
Dnipro Radar, Aeroflot 1816
Controller:
Aeroflot 1816, Dnipro Radar, go ahead
Pilot:
Request descent, Aeroflot 1816
Controller:
Aeroflot 1816, descend to altitude 6,000 feet
Pilot:
Descending to altitude 6,000 feet, Aeroflot 1816

В этом разделе мы изучили основы взаимодействия потоков и рассмотрели приме приложения с его применением.