Рекомендуємо, 2024

Вибір Редакції

Різниця між класом Thread і інтерфейсом Runnable в Java

Потік можна визначити двома способами. По-перше, розширюючи клас Thread, який вже реалізував інтерфейс Runnable. По-друге, безпосередньо реалізуючи інтерфейс Runnable . Коли ви визначаєте потік, розширюючи клас Thread, ви повинні перевизначити метод run () у класі Thread. При визначенні потоку, що реалізує інтерфейс Runnable, необхідно реалізувати тільки метод run () інтерфейсу Runnable. Основна відмінність між Thread і Runnable полягає в тому, що кожен потік, визначений розширенням класу Thread, створює унікальний об'єкт і пов'язується з цим об'єктом. З іншого боку, кожен потік, визначений за допомогою реалізації Runnable інтерфейсу, поділяє один і той же об'єкт.

Давайте розглянемо деякі інші відмінності між Thread і Runnable за допомогою діаграми порівняння, показаної нижче:

Діаграма порівняння

Основа для порівнянняНиткаRunnable
ОсновнийКожен потік створює унікальний об'єкт і пов'язується з ним.Кілька потоків мають спільні об'єкти.
Пам'ятьОскільки кожен потік створює унікальний об'єкт, потрібно більше пам'яті.Оскільки декілька потоків мають спільний об'єкт, використовується менше пам'яті.
РозширенняУ Java багатократне успадкування не допускається, отже, після того, як клас розширює клас Thread, він не може поширювати будь-який інший клас.Якщо клас визначає потік, що реалізує інтерфейс Runnable, він має шанс розширити один клас.
ВикористовуйтеКористувач повинен розширити клас потоків, лише якщо він хоче перекрити інші методи класу Thread.Якщо ви тільки хочете, щоб спеціалізувати запустити метод, то реалізація Runnable є кращим варіантом.
МуфтаРозширюючий клас Thread вводить жорсткий зв'язок, оскільки клас містить код класу Thread, а також завдання, призначене для потокуРеалізація інтерфейсу Runnable вводить вільну зв'язок, оскільки код Thread є окремою формою завдання Threads.

Визначення класу ниток

Thread - це клас у пакеті java.lang . Клас Thread розширює клас Object і впроваджує інтерфейси Runnable . Клас Thread має конструктори та методи для створення та роботи з потоком. Коли ми створюємо кілька потоків, кожен потік створює унікальний об'єкт і отримує асоційований з ним об'єкт. Якщо ви створюєте клас потоку, що розширює потік, далі не можна розширювати будь-який інший клас, оскільки java не підтримує багаторазове успадкування. Отже, ви повинні розширити клас Thread тільки тоді, коли ви також бажаєте перевизначити деякі інші методи класу Thread. Подивимося приклад створення потоку, що розширює клас Thread.

 / * Визначення потоку * / Class Mythread розширює Thread {/ * завдання потоку * / public void run () {for (int i = 0; i <10; i ++) {System.Out.Println ("Дитяча нитка") ); }} Клас mainThread {/ * завдання головного потоку * / public static void main (String args []) {Mythread mt = new Mythread (); / * головний потік створив дочірній потік * / mt.start (); для (int i = 0; i <10; i ++) {System.Out.Print ("Головна тема"); Дитяча нитка Дитяча нитка Дитяча нитка Дитяча нитка Дитяча нитка Дитяча нитка Головна тема Нитка дитяча нитка Дитяча нитка Головна тема Нитка дитяча нитка дитяча нитка Головна тема 

У наведеному вище коді я створюю клас Mythread, який розширює клас Thread і перекриває метод run у класі Thread. У класі, що містить основний метод, я створюю об'єкт потоку (mt) класу Mythread і використовуючи об'єкт потоку, викликаний метод start (). Метод start запускає виконання потоку і в той же час JVM викликає запуск методу потоку. Тепер у програмі є два потоки одного основного потоку і другого дочірнього потоку, створеного основним потоком. Виконання обох потоків відбувається одночасно, але точний вихід не можна прикидати.

Визначення Runnable інтерфейсу

Runnable - це інтерфейс у пакеті java.lang . Реалізуючи Runnable інтерфейс, ми можемо визначити потік. Runnable інтерфейс має єдиний метод run (), який реалізується класом, що реалізує Runnable інтерфейс. Якщо ви вирішите визначити потік, що реалізує інтерфейс Runnable, у вас все ще є можливість розширити будь-який інший клас. Коли ви створюєте кілька потоків, реалізуючи інтерфейс Runnable, кожен потік поділяє той самий виконаний екземпляр. Давайте дізнаємося, як визначити потік за допомогою інтерфейсу Runnable.

 / * Визначення потоку * / Клас Runnablethread реалізує Runnable {/ * завдання потоку * / public void run () {for (int i = 0; i <10; i ++) {System.Out.Println ("Дитяча нитка") ); }} Клас mainThread {/ * завдання головного потоку * / public static void main (String args []) {Mythread rt = new Mythread (); / * головний потік створив об'єкт, що виконується * / Thread t = new Thread (rt); / * головний потік створює дочірній потік і передає виконуваний об'єкт * / t.start (); для (int i = 0; i <10; i ++) {System.Out.Print ("Головна тема"); Дитяча нитка Дитяча нитка Дитяча нитка Дитяча нитка Дитяча нитка Дитяча нитка Головна тема Нитка дитяча нитка Дитяча нитка Головна тема Нитка дитяча нитка дитяча нитка Головна тема 

У наведеному вище коді я створив клас Runnablethread, який реалізує інтерфейс Runnable і визначає завдання потоку, реалізуючи метод run () інтерфейсу Runnable. Потім я створюю клас mainthread, що містить основний метод. Усередині основного методу я оголосив об'єкт runnable класу Runnablethread і передав цей об'єкт конструктору Thread, оголошуючи потік. Таким чином, я пов'язав об'єкт потоку (t) з об'єктом, що виконується (rt). Потім об'єкт потоку викликає метод start потоку, який додатково викликає метод run для класу Runnablethread. Якщо я не зв'язав об'єкт, що виконується, з об'єктом Thread, то метод запускання потоків викликав би метод виконання класу Thread. Тепер, знову є два потоки в коді, головний потік і головний потік створює дочірній потік, і виконуються одночасно, але точний висновок ніколи не можна прикидати.

Основні відмінності між ниткою і виконуваним в Java

  1. Кожен потік, створений розширенням класу Thread, створює для нього унікальний об'єкт і зв'язується з ним. З іншого боку, кожен потік, створений за допомогою реалізованого інтерфейсу Runnable, має один і той же виконуваний екземпляр.
  2. Оскільки кожен потік пов'язаний з унікальним об'єктом при створенні класу Thread, потрібно більше пам'яті. З іншого боку, кожен потік, створений за допомогою реалізації Runnable інтерфейсу, поділяє один і той же об'єктний простір, отже, він вимагає менше пам'яті.
  3. Якщо ви продовжите клас Thread, то ви зможете успадковувати будь-який інший клас, оскільки Java не допускає багаторазове успадкування, тоді як реалізація Runnable все ще дає можливість класу наслідувати будь-який інший клас.
  4. Необхідно розширити клас Thread, лише якщо він повинен перекрити або спеціалізувати деякі інші методи класу Thread. Необхідно реалізувати інтерфейс Runnable, якщо потрібно лише спеціалізувати метод виконання.
  5. Розширення класу Thread вводить жорсткий зв'язок в коді, оскільки код Thread і завдання потоку міститься в одному класі. З іншого боку, реалізація Runnable інтерфейсу вводить вільну зв'язок в коді, оскільки код Thread є seprate з завдання, призначеного для потоку.

Висновок:

Краще реалізувати інтерфейс Runnable замість розширення класу Thread. Як реалізація Runnable робить ваш код вільно пов'язаний, оскільки код потоку відрізняється від класу, який призначає завдання потоку. Вона вимагає менше пам'яті, а також дозволяє класу наслідувати будь-який інший клас.

Top