Concurrency

Motivation

Problem

  • Современные устройства имеют несколько физических или виртуальных ядер.

  • Это значит они могут выполнять параллельно несколько различных задач.

  • Но программы, которые разрабатывались раннее, выполняются последовательно.

  • Соответственно работают медленнее чем мог ли бы.

  • Как повысить производительность программы, и утилизировать ресурс современных CPU?

Solution

  • Использовать многопоточность.

  • Java Concurrency.

Concurrency

Definition Multi

  • Multiprogramming – A computer running more than one program at a time (like running Terminal and Firefox simultaneously).

  • Multiprocessing – A computer using more than one CPU at a time.

  • Multitasking – Tasks sharing a common resource (like 1 CPU).

  • Multithreading is an extension of multitasking

Multiprogramming

Multithreading

Multiprocessing

Multithreading

Multitasking

Multithreading

Multithreading

Multithreading

Differentiation

Multithreading

Java Concurrency

Java Concurrency

  • Concurrency требует внимательной работы от разработчика, т.к.:

    • Программа одновременно имеет несколько потоков выполнения.

    • Потоки работают с общей памятью (Heap один для всех потоков).

    • Потокам необходимо взаимодействовать (синхронизироваться) друг с другом.

Class Thread

Example

public static void main(String[] args) {
    Thread t = Thread.currentThread();
    System.out.println(t.getName());
}
main

Fields

  • Основные поля:

    • id – идентификатор потока

    • name – имя потока

    • daemon – поток-демон

    • priority – приоритет

  • Эти поля не могут меняться после запуска потока.

Methods

  • getID(): long

  • final getName(): String

  • final setName(String): void

  • final getPriority(): int

  • final setPriority(int): void

  • final isDaemon():boolean

  • final setDaemon(boolean): void

Priority

Priority

  • Определяется значениями от 1 до 10

  • Но есть предопределенные константы:

    • Thread.MIN_PRIORITY = 1

    • Thread.NORM_PRIORITY = 5

    • Thread.MAX_PRIORITY = 10

Creating Thread

Ways to create

  • By extending Thread class

  • By implementing Runnable interface

    • as Class

    • as Anonymous Class

Constructors

  • Thread()

  • Thread(String name)

  • Thread(Runnable r)

  • Thread(Runnable r, String name)

By extending Thread class

class Multi extends Thread {
    @Override
    public void run() {
        System.out.println("thread is running...");
    }
}
class Program {
    public static void main(String[] args) {
        Thread t1 = new Multi();
        t1.start();
    }
}

Implementing Runnable interface

class Multi3 implements Runnable {
    public void run() {
        System.out.println("thread is running...");
    }
}
class Program {
    public static void main(String[] args) {
        Multi3 m1 = new Multi3();
        Thread t1 = new Thread(m1);
        t1.start();
    }
}

Methods

  • start(): void

  • run(): void

  • interrupt(): void

  • final join(): void

  • getState(): Thread.State

  • final isAlive(): boolean

  • isInterrupted(): boolean

Methods

  • static sleep(long): void

  • static interrupted(): boolean

  • static currentThread(): Thread

  • static yield(): void

  • static holdsLock(Object о): boolean

Thread Lifecycle

Thread Lifecycle

Thread lifecycle

Thread state

getState()

isAlive()

NEW

false

RUNNABLE

true

BLOCKED

true

WAITING

true

TIMED_WAITING

true

TERMINATED

false

RUNNABLE

Thread lifecycle

RUNNABLE

  • yield() – передать ресурс CPU другому потоку

  • Методы в процессе выполнения бросаются InterruptedException

WAITING

Thread lifecycle

WAITING

  • Перевести поток в состояние WAITING (ожидающий):

    • wait()

    • join() – ожидать до завершения потока

WAITING → RUNNABLE

Thread lifecycle

WAITING → RUNNABLE

  • Вернуть работоспособность потоку:

    • notify()

    • notifyAll()

TIMED_WAITING

Thread lifecycle

TIMED_WAITING

  • Перевести поток в состояние TIMED_WAITING (ожидающий по времени):

    • wait(long millis)

    • sleep(long millis)

    • join(long millis) – ожидать до завершения или истечения millis миллисекунд

TERMINATED

Thread lifecycle

TERMINATED

  • Перевести поток в состояние TERMINATED (завершенный):

  • interrupt() – выполняется только для работоспособного потока

  • метод run() завершил выполнение

  • метод run() завершает свою работу по какому-то условию (или работает бесконечно)

Локальная память для потока

Локальная память для потока

  • Класс java.lang.ThreadLocal<T> используется для хранения переменных, которые должны быть доступны для ТОЛЬКО для текущего потока.

  • Имеет методы:

    • get(): T

    • set(T): void

    • remove(): void

Группа потоков

Группа потоков

  • Группа потоков исполнения - это структура данных, которая управляет состоянием всего ряда потоков исполнения в целом.

  • Каждая группа потоков исполнения представляется объектом класса ThreadGroup.

  • Группа потоков также может включать в себя другие группы потоков.

Группа потоков

  • Группы потоков (thread groups) улучшают вопросы, связанные с управляемостью и безопасностью, а именно:

    • Можно прервать работу сразу всех потоков группы.

    • Установить для них единое максимальное значение приоритета выполнения.

    • Наложить ограничения на способность потоков, принадлежащих группе, выполнять те или иные действия.

Total

Total

  • Concurrency достаточно объемная и сложная тема

  • Concurrency требует переосмысления подходов при написании кода