Java Threads
Оновлено: 22.05.2023
Потоки Java
Потоки дозволяють програмі працювати ефективніше, виконуючи кілька завдань одночасно.
Потоки можна використовувати для виконання складних завдань у фоновому режимі, не перериваючи основну програму.
Створення нитки
Існує два способи створення потоку.
Його можна створити, розширивши клас Thread і перевизначивши його метод run():
public class Main extends Thread {
public void run() {
System.out.println("This code is running in a thread");
Іншим способом створення потоку є реалізація інтерфейсу Runnable:
public class Main implements Runnable {
public void run() {
System.out.println("This code is running in a thread");
}
}
Нитки, що біжать
Якщо клас розширює клас Thread, то потік можна запустити, створивши екземпляр класу і викликавши його метод start():
public class Main extends Thread {
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
Якщо клас реалізує інтерфейс Runnable, то потік можна запустити, передавши екземпляр класу в конструктор об'єкту Thread, а потім викликавши метод start() потоку:
public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
Проблеми паралелізму
Оскільки потоки виконуються одночасно з іншими частинами програми, неможливо передбачити, в якому порядку буде виконуватися код. Коли потоки і основна програма читають і записують одні й ті ж змінні, їх значення непередбачувані. Проблеми, які виникають внаслідок цього, називаються проблемами паралелізму.
Приклад коду, в якому значення змінної amount є непередбачуваним:
public class Main extends Thread {
public static int amount = 0;
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println(amount);
amount++;
System.out.println(amount);
public void run() {
amount++;
Щоб уникнути проблем з паралелізмом, найкраще використовувати якомога менше атрибутів між потоками. Якщо атрибути необхідно використовувати спільно, одним з можливих рішень є використання методу isAlive() потоку для перевірки завершення роботи потоку перед використанням будь-яких атрибутів, які потік може змінювати.
Використовуйте isAlive() для запобігання проблемам паралелізму:
isAlive()
public class Main extends Thread {
public static int amount = 0;
public static void main(String[] args) {
Main thread = new Main();
thread.start();
// Wait for the thread to finish
while(thread.isAlive()) {
System.out.println("Waiting...");
// Update amount and print its value
System.out.println("Main: " + amount);
amount++;
System.out.println("Main: " + amount);
public void run() {
amount++;