Що було б, якби ми могли виконувати кілька частин коду одночасно? Це було б чудово, чи не так? Зазвичай у Java програмах працює лише один потік. Тут ми розглянемо, як можна виконувати кілька частин коду за допомогою потоків (threads) одночасно.
Ось кілька вбудованих методів для роботи з потоками, які можуть бути корисними при роботі з потоками.
- sleep(long millis): паузить потік перед продовженням виконання потоку.
- isAlive(): повертає true або false в залежності від стану потоку.
- .join(): порушує призначення потоків, оскільки чекає завершення виконання іншого потоку.
В Java є два способи створення потоку.
- Клас Thread: Клас буде наслідувати клас Thread, дозволяючи перевизначити метод run, де потоки виконуватимуть програму. Це не рекомендований спосіб, оскільки в такому випадку ви не зможете наслідувати інші класи.
public class MultiThreading extends Thread{
private int threadNumber;
public MultiThreading(int threadNumber) {
this.threadNumber = threadNumber;
}
@Override
public void run(){
for(int i=0;i<5;i++){
System.out.println( "from inside the thread " + this.threadNumber );
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static void main(String[] args) throws InterruptedException {
for(int i=0;i<3;i++){
MultiThreading thread = new MultiThreading(i);
thread.start();
System.out.println(thread.isAlive());
}
}
- Інтерфейс Runnable: Це працює так само, як клас Thread, але цей спосіб створення рекомендований, оскільки дозволяє вам наслідувати будь-які інші класи та реалізувати стільки інтерфейсів, скільки потрібно.
На відміну від класу Thread, де змінна посилання на розширений клас Thread використовується для запуску потоку, тут ми не можемо зробити те ж саме. Нам потрібно передавати змінну посилання до об'єкта Thread, який ми створюємо.
public class MultiThreadingInterface implements Runnable{
private int threadNumber;
public MultiThreadingInterface(int threadNumber) {
this.threadNumber = threadNumber;
}
@Override
public void run() {
for (int i=0;i<5;i++){
System.out.println("Inside the thread interface " + this.threadNumber);
try {
Thread.sleep(100);
}catch (InterruptedException e){
System.out.println(e);
}
}
}
}
public static void main(String[] args) throws InterruptedException {
for(int i=0;i<3;i++){
MultiThreadingInterface thread1 = new MultiThreadingInterface(i);
Thread th = new Thread(thread1);
th.start();
System.out.println(thread.isAlive());
}
}
Примітка: Виняток або завершення потоку не впливають на інші потоки, які виконуються.
Synchronized: блокує відповідний клас, не дозволяючи іншому потоку виконувати цей код або метод.
class Display{
synchronized void print(){
for (int i=0;i<5;i++){
try{
Thread.sleep(50);
System.out.println(Thread.currentThread().getName());
}catch (Exception e){}
}
}
}
class PrinterA implements Runnable{
private final Display display;
public PrinterA(Display display){
this.display = display;
}
@Override
public void run(){
display.print();
}
}
public class MutiThreading {
public static void main(String[] args) {
Display display = new Display();
PrinterA printerA = new PrinterA(display);
PrinterA printerb = new PrinterA(display);
Thread th = new Thread(printerA);
Thread th1 = new Thread(printerb);
th.start();
th1.start();
}
}
Перекладено з: [MutliThreading in Java](https://medium.com/@muhasheikh8/mutlithreading-in-java-ab81956217ce)