• ,

Уровень 28. Ответы на вопросы к собеседованию по теме уровня.

Всем привет!
Решил продолжить обучение на джавараше, несмотря на то, что работу по java я уже нашел.
Дисклеймер:
Этот блог я веду для самого себя, очень лениво, и, можно сказать, из под палки. Я буду очень рад, если он окажется для кого-то полезным, однако не стоит использовать его в качестве основного источника для поиска ответов на вопросы уровня.

1 Какие приоритеты нитей бывают?
Каждый поток в системе имеет свой приоритет. Приоритет – это некоторое число в объекте потока от 1 до 10, более высокое значение которого означает больший приоритет. Система в первую очередь выполняет потоки с большим приоритетом, а потоки с меньшим приоритетом получают процессорное время только тогда, когда их более привилегированные собратья простаивают.

Работать с приоритетами потока можно с помощью двух функций:

void setPriority(int priority) //устанавливает приоритет потока.

Возможные значения priority — MIN_PRIORITY, NORM_PRIORITY и MAX_PRIORITY.

int getPriority() // получает приоритет потока.

Источник
Если приоритет не задан, то нить получает приоритет 5 — средний.

Приоритет нити не сильно влияет на ее работу, а носит скорее рекомендательный характер. Если есть несколько спящих нитей, которые нужно запустить, то Java-машина сначала запустит нить с более высоким приоритетом.

Java-машина управляет нитями так, как посчитает нужным. Нити с низким приоритетом не будут простаивать. Просто они будут получать меньше времени, чем другие, но выполняться все равно будут.

В большинстве случаев нити всегда выполняются с одинаковым приоритетом. Попытка дать одной нити больше времени, чем другим, часто указывает на архитектурную ошибку программы.

2 Можно ли остановить нить, снизив ее приоритет до 0?
Нет. Будет брошен IllegalArgumentException

3 Зачем нужен класс ThreadGroup?

Чтобы любая нить не могла останавливать и прерывать все нити подряд, было введено понятие «группы нитей». Нить может оказывать влияние только на другие нити, которые содержатся в той же группе, что и она. ThreadGroup – это класс, который управляет группами нитей. Такой подход позволяет защитить нити от нежелательного изменения.

Иногда приходится выполнять код, которому нельзя 100% доверять. Поэтому удобно поместить все его нити в отдельную группу и запретить им вмешиваться в работу основной группы нитей.

Иными словами для управления группами потоков

4 В какой группе нитей состоит main-thread?
main

5 Что такое паттерн ThreadPool
Паттерн ThreadPool общими словами — группа потоков, которые решают группы задач. Задачи организованы в очередь. Как только поток завершает работу над задачей, он запрашивает следующую задачу из очереди, до тех пор, пока все задачи в очереди не будут выполнены. После этого поток может завершиться, либо уснуть, до тех пор, пока в очереди не появятся новые задачи.

6 Зачем нужен класс ThreadPoolExecutor?
Для решения большого количества небольших задач группой потоков. Использование класса позволяет избегать расточительного использования ресурсов машины. Тк Создавать для каждой задачи свою нить бывает не очень рационально. Для каждой нити Java-машина выделяет довольно много ресурсов.
Другими словами – создание и уничтожение отработавшей нити может тратить больше ресурсов и времени, чем само выполняемое задание.
Java-разработчики придумали элегантное решение этой проблемы — ThreadPoolExecutor.
ThreadPoolExecutor – это класс, который имеет внутри две вещи:
А) Очередь задач, в которую можно добавлять задачи, по мере их появления в программе.
Б) Пул-нитей (группа нитей) – которые эти задачи исполняют.
При этом нити не уничтожаются после выполнения задания, а засыпают. Чтобы начать выполнять новое задание, как только оно появится.

7 Сколько способов создать нить вы знаете? (Thread, Runnable, Callable)
public class ThreadsTests {
    //Способ 1
    static class ThreadExampleRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    
    //Способ 2
    static class ThreadExampleFromThread extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }

    //Способ 3
    static class ThreadExampleFromCallable implements Callable{
        @Override
        public String call() throws Exception {
            return Thread.currentThread().getName();
        }
    }
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        new Thread(new ThreadExampleRunnable()).start(); //Способ 1
        new ThreadExampleFromThread().start(); //Способ 2

        //Способ 3
        ExecutorService service = Executors.newFixedThreadPool(5);
        Future<String> task = service.submit(new ThreadExampleFromCallable());
        System.out.println(task.get());

    }
}


8 Для чего используется класс Future?
Этот объект можно использовать, чтобы узнать, завершилось ли уже выполнение задачи, а также, чтобы получить результат ее выполнения.
boolean cancel(boolean mayInterrupt); // Останавливает задачу. 
boolean isCancelled(); //Возвращает true, если задача была остановлена.
boolean isDone(); //Возвращает true, если выполнение задачи завершено.
V get() throws InterruptedException, ExecutionException; //Возвращает результат вызова метода call или кидает исключение, если оно было.


9 В чем преимущества Callable над Runnable?
Используя Callable мы можем узнать завершилась ли задача, и узнать её результат, гораздо проще, чем при использовании Runnable

10 Можно ли отменить выполнение задачи, если использовать класс Future?
Можно, если задача лежит в очереди и ожидает своего исполнения, иначе не факт