JavaRush /Java блог /Random UA /Рівень 28. Відповіді на запитання до співбесіди на тему р...
DefNeo
36 рівень

Рівень 28. Відповіді на запитання до співбесіди на тему рівня

Стаття з групи Random UA
Рівень 28. Відповіді на запитання до співбесіди на тему рівня - 1
  1. Які пріоритети ниток бувають?

    Відповідь це питання є у лекціях JavaRush.

    Для оптимізації паралельної роботи ниток у Java можна встановлювати пріоритети ниток. Нитки з пріоритетом мають перевагу в отриманні часу процесора перед нитками з нижчим пріоритетом.

    Робота з пріоритетами забезпечується такими методами класу Thread:

    public final void setPriority(int newPriority)

    Встановлює пріоритет нитки.

    public final int getPriority()

    Дозволяє дізнатися пріоритет нитки.

    Значення параметра в методі setPriorityне може бути довільним. Воно має бути в межах від MIN_PRIORITY до MAX_PRIORITY . При створенні нитка має пріоритет NORM_PRIORITY .

    MIN_PRIORITY = 1.
    NORM_PRIORITY = 5.
    MAX_PRIORITY = 10.

  2. Чи можна зупинити нитку, зменшивши її пріоритет до 0?

    Відповідь у статті: «Топ 50 питань на співбесіді. Тема: Багатопотоковість (Multithreading)»

    Знайшов на форумі.

    Є варіант цієї статті англійською мовою: Java Thread Interview Questions

    Java надає багаті API для всього, але за іронією долі не надає зручних способів зупинки нитки. У JDK 1.0 було кілька керуючих методів, наприклад stop(), suspend()і resume(), які були помічені як deprecated в майбутніх релізах через потенційні загрози взаємного блокування, з тих пір розробники Java API не зробабо спроб представити стійкий, нитко-безпечний і елегантний спосіб зупинки ниток. Програмісти в основному покладаються на факт того, що нитка зупиняється сама, як тільки закінчує виконувати методи run()або call(). Для зупинки вручну програмісти користуються перевагою volatile booleanзмінної і перевіряють її значення в кожній ітерації, якщо в методі run()є цикли, або переривають нитки методомinterrupt()для раптового скасування завдань.

    Саме з питання: Ніде не бачив, щоб хтось пріоритет виставляв у 0.

    Якщо хтось знає про це щось, то напишіть у коментарях.

  3. Навіщо потрібен клас ThreadGroup?

    ThreadGroupявляє собою набір ниток, які можуть містити в собі інші групи потоків. Група ниток утворює дерево, де кожна інша група ниток має батька (крім вихідної). Потік має право доступу до даних зі своєї групи ниток, але не має такого доступу до інших груп або батьківської групи потоків.

  4. У якій групі ниток полягає main-thread?

    Ніде не знайшов)) Підкажіть де це є))

  5. Що таке патерн ThreadPool?

    На це є витяг зі статті на вікіпедії:

    У комп'ютерному програмуванні, ліміт полів pattern (також помічений робітників або роботодавець-модель) є тим, що число дій є створеним для виконання числа дій, які є зазвичай організовані в кліті. Результати від дій можуть бути виконані засобом або бути placed in queue, або дії можливі повернення не результат (для прикладу, якщо дія є для animation). Typically, there are many more tasks than threads. Як деякий час, як загрожують його завдання, це буде потреба в наступній ході від неповноцінних всіх рішень, які повинні бути виконані. Підліток може бути виконаний, або sleep until є нові tasks available.

    Число threads used is a parametr that can be tuned to provide best performance. До того ж, число threads може бути dynamic based on the number of waiting tasks. Для прикладу, веб-сервер може підтримувати сторінки, якщо багато веб-сторінок повідомлень проходять і можуть керувати треками, коли ці потреби перевищують. Спосіб має велику thread pool is increased resource usage. algoritm, який використовується для визначення, коли створюється або позбавиться threads буде мати impact on overall performance:

    • create too many threads, and resources are wasted and time also wasted creating any unused threads
    • destroy too many threads and more time will be spent later creating them again
    • створення threads too slowly might result in poor client performance (long wait times)

    У комп'ютерному програмуванні є модель пула потоків, де кілька потоків створюється до виконання цілого ряду завдань, які зазвичай організовуються у черзі. Результати від виконаних завдань також можуть бути поміщені в чергу або завдання можуть не повертати жодного результату (наприклад, якщо завдання для анімації).

    Як правило, є набагато більше завдань, ніж потоків. Як тільки потік завершить своє завдання, він вимагатиме наступне завдання з черги, поки всі завдання не будуть завершені. Потік може потім перерватися чи заснути. Кількість потоків, що використовуються, це параметр, який може бути налаштований, для забезпечення найкращої продуктивності. Крім того, число потоків може бути динамічним на основі кількості завдань, що виникають. Наприклад, веб-сервер може додавати потоки, якщо запити численних веб-сторінок надходять і може видалити потоки, коли цих запитів стає менше. Зі збільшенням розміру пулу потоків збільшується використання ресурсів комп'ютера. Алгоритм, який використовується для визначення того, коли створювати чи знищувати потоки, матиме вплив на загальну продуктивність:

    Знищення занадто багато потоків і більше часу буде витрачено пізніше знову для їх створення - Створення потоків занадто повільно може призвести до зниження продуктивності клієнта.

  6. Навіщо потрібен клас ThreadPoolExecutor?

    public class ThreadPoolExecutor extends AbstractExecutorService

    ExecutorServiceце виконує кожну подану задачу, використовуючи один можливо з декількох об'єднаних в пул потоків, зазвичай налаштоване використання Executorsметоди фабрики.

    Пули потоків розглядають дві різні проблеми: вони зазвичай забезпечують покращену продуктивність, виконуючи великі кількості асинхронних завдань, через зменшені витрати виклику на завдання, і вони забезпечують засіб обмеження та управління ресурсами, включаючи потоки, використані, виконуючи набір завдань. Кожен ThreadPoolExecutorтакож підтримує трохи основної статистики, як-от число завершених завдань.

    Щоб бути корисним через широкий діапазон контекстів, цей клас забезпечує багато параметрів, що коригуються, і важелів розширюваності. Проте, програмістів переконують використовувати зручніше Executorsметоди фабрики Executors.newCachedThreadPool()(необмежений пул потоків, з автоматичним відновленням потоку), Executors.newFixedThreadPool(int)(пул потоків фіксованого розміру) та Executors.newSingleThreadExecutor()(єдиний фоновий потік), які попередньо конфігурують налаштування для найпоширеніших сценаріїв використання.

  7. Скільки способів створити нитку ви знаєте?

    На рівні мови є два способи створення нитки. Об'єкт класу java.lang.Threadє ниткою, але їй потрібне завдання для виконання, яка є об'єктом, що реалізує інтерфейс java.lang.Runnable. Так як клас Threadреалізує інтерфейс Runnable, ви можете перевизначити метод run()успадкувавши ваш клас від Threadабо реалізувавши в ньому інтерфейс Runnable.

  8. Для чого використовується клас Future?

    Futureзберігає результат асинхронного обчислення. Ви можете запустити обчислення, надавши кому-небудь об'єкт Futureі забути про нього. Власник об'єкта Futureможе отримати результат, коли він буде готовим.

  9. У чому переваги Callableнад Runnable?

    Посилання: Частина 2. Виконання завдань у багатопотоковому режимі

    Інтерфейс Callableнабагато більше підходить для створення завдань, призначених для паралельного виконання, ніж інтерфейс Runnableабо тим більше клас Thread. При цьому варто відзначити, що можливість додати подібний інтерфейс з'явилася лише з версії Java 5, оскільки ключова особливість інтерфейсу Callable– це використання параметризованих типів (generics), як показано у лістингу.

    Листинг створення задачи с помощью интерфейса Callable
    10	1 import java.util.concurrent.Callable;
    11	2 public class CallableSample implements Callable{
    12	3     public String call() throws Exception {
    13	4         if(якое-то умова) {
    14	5             throw new IOException("error during task processing");
    15	6         }
    16	7         System.out.println("task is processing");
    17	8         return "result ";
    18	9     }
    19	10 }
    

    Відразу необхідно звернути увагу на рядок 2, де зазначено, що інтерфейс Callableє параметризованим, і його конкретна реалізація – клас CallableSampleзалежить від типу String. На рядку 3 наведена сигнатура основного методу callвже параметризованому варіанті, так як в якості типу значення, що повертається також зазначений тип String. Фактично це означає, що було створено завдання, результатом виконання якого буде об'єкт типу String(див. рядок 8). Точно також можна створити завдання, в результаті роботи якого в методі callстворюватиметься і повертатиметься об'єкт будь-якого необхідного типу. Таке рішення значно зручніше порівняно з методом run в інтерфейсі Runnable, який не повертає нічого (його тип, що повертається –void) і тому доводиться винаходити обхідні шляхи, щоб отримати результат роботи завдання.

    Ще одна перевага інтерфейсу Callable– це можливість «викидати» виняткові ситуації, не впливаючи на інші завдання, що виконуються. На рядку 3 зазначено, що з методу може бути викинута виняткова ситуація типу Exception, що фактично означає будь-яку виняткову ситуацію, так як всі винятки є нащадками java.lang.Exception. На рядку 5 ця можливість використовується створення контрольованої (checked) виняткової ситуації типу IOException. Метод runінтерфейсу Runnableвзагалі не допускав викидання контрольованих виняткових ситуацій, а викид неконтрольованої (runtime) виняткової ситуації призводив до зупинки потоку та всього додатка.

  10. Чи можна скасувати виконання завдання, якщо використати клас Future?

    Виходячи з цієї дискусії , піднятої на хабрі, виходить, що не можна.

    Є Futureметод Future.cancel(boolean), який має скасувати виконання завдання. Але якщо завдання вже почало виконуватися, виклик Future.cancel(true)насправді не зупинить його. У надрах реалізації FutureTaskвиконується код:

    if (mayInterruptIfRunning) {
    Thread r = runner;
    if (r != null)
    r.interrupt(); }

    Тобто. знову потоку, у якому виконується завдання, лише рекомендується припинити виконання. До того ж, ми не маємо навіть можливості дізнатися, чи виконується завдання в даний момент, чи ні. Є метод Future.isDone(), але знову мимо, він повертає true не тільки коли завдання завершило виконання, а відразу після виклику Future.cancel(), навіть якщо завдання все ще виконується (адже Future.cancel(true)не зупиняє завдання, яке вже почало виконуватися).

    Добре, якщо ми пишемо весь код, тоді можна в потрібних місцях акуратно обробляти Thread.isInterrupted()і все буде ОК. Але якщо ми запускаємо код? Якщо у нас є сервер, що розширюється за допомогою плагінів? Який-небудь криво написаний плагін може запитто призвести до непрацездатного стану весь сервер адже ми не можемо коректно перервати виконання плагіна, що завис.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ