Бесплатный курс по Java: от основ до продвинутого уровня
Интерфейс Runnable в Java
Реализуя Runnableтоже реализуется метод run в котором пишется код, который будет выполняться в отдельном потоке.
Пример программы:
//Создадим простенький класс.
//Дальше поясним зачем он.
class Friend {
public static void m1() {
System.out.println(“Hello Friend!!!”);
}
}
//Также можно увидеть что мы реализуем не только
//Runnable но и расширяем Friend. Это преимущество
//реализации Runnable перед расширением Thread
//так как в Java можно расширять Лишь Один класс
//и если бы мы расширили Thread то расширить
//какой либо другой класс (например Friend)
//уже не имели бы возможности.
class MyThread extends Friend implements Runnable {
int i=0;
public void run() {
i++;
m1();
}
}
class RunnableExample {
public static void main(String[] args) {
//создаем один объект MyThread.
MyThread MyThr = new MyThread();
//Можно у одного объекта
//в отдельных потоках запускать его метод run
//это преимущество Runnable перед Thread.
//Подробнее на следующей странице.
Thread t1 = new Thread(MyThr);//передается в поток
Thread t2 = new Thread(MyThr);//передается в поток 2 раз
//run объекта MyThr запускается
//в отдельных потоках t1 и t2.
t1.start();
t2.start();
//Еще одно преимущество Runnable перед Thread
//что код класса реализующего Runnable можно
//использовать вне в отдельном потоке.
//То есть m1 просто выполнится здесь в потоке метода main
MyThr.m1();
//В конце можно увидеть 2. То есть оба потока работали
//с одним и тем же объектом.
//Все потоки добавили 1 к полю i объекта MyThr.
System.out.println(MyThr.i);
}
}
Вывод:
В консоли можно увидеть 2. То есть оба потока работали с одним и тем же объектом. Все потоки добавляли 1 к полю i объекта MyThr.
Преимущества реализации Runnable
Преимущества реализации Runnable перед расширением Thread:
1. Реализуя Runnable можно создать всего 1 объект и передавать в потоки для параллельного выполнения, в отличие от расширения thread, где для каждого потока необходимо создавать отдельный объект класса, который расширяет Thread.
То есть мы видели в прошлом уроке:
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
Следовательно реализуя Runnable можно сэкономить память, не создавая кучу объектов.
Также нужно помнить, что раз все потоки работают с одним объектом, то они работают с одними и теми же самыми полями этого одного объекта.
2. Код класса реализующего Runnable можно использовать не в потоке. Объект можно передать не только в Thread, а и, например, в ExecutorService
3. Расширяя Thread нет возможности расширить класс расширяющий Thread еще раз, так как в java нет множ. насл.
Разберитесь с ключевым словом volatile в Java: как оно обеспечивает видимость изменений переменной для всех потоков. Практический пример использования.
Time to read: 9
Метод join в Java
Узнайте, как метод join() в Java приостанавливает текущий поток до завершения другого. Примеры кода и объяснение работы с потоками для эффективной синхронизации.
Time to read: 11
Синхронизация в Java с помощью Synchronized
Изучите synchronized в Java: как организовать поочередный доступ потоков к общему ресурсу. Пример кода с пояснением работы синхронизации.