Поиск по сайту:

Java Multithreading Concurrency Interview Вопросы и ответы


Сегодня мы рассмотрим вопросы и ответы на собеседовании по Java Multithreading. Мы также рассмотрим вопросы и ответы на собеседованиях по параллелизму, потому что и многопоточность, и параллелизм идут рука об руку. Тема — одна из популярных тем в вопросах на собеседовании по Java. Здесь я перечисляю большинство важных вопросов о многопоточности Java с точки зрения собеседования, но вы должны иметь хорошие знания о потоках Java, чтобы иметь дело с дополнительными вопросами.

Вопросы для собеседования по многопоточности в Java

  1. В чем разница между процессом и потоком?
  2. Каковы преимущества многопоточного программирования?
  3. В чем разница между потоком пользователя и потоком демона?
  4. Как мы можем создать поток в Java?
  5. Каковы разные состояния жизненного цикла потока?
  6. Можем ли мы вызвать метод run() класса Thread?
  7. Как мы можем приостановить выполнение потока на определенное время?
  8. Что вы понимаете о приоритете потока?
  9. Что такое планировщик потоков и разделение времени?
  10. Что такое переключение контекста в многопоточности?
  11. Как мы можем убедиться, что main() является последним потоком, который завершится в Java-программе?
  12. Как потоки взаимодействуют друг с другом?
  13. Почему методы связи потоков wait(), notify() и notifyAll() относятся к классу Object?
  14. Почему методы wait(), notify() и notifyAll() должны вызываться из синхронизированного метода или блока?
  15. Почему методы Thread sleep() и yield() являются статическими?
  16. Как мы можем обеспечить безопасность потоков в Java?
  17. Что такое ключевое слово volatile в Java?
  18. Что предпочтительнее — синхронизированный метод или синхронизированный блок?
  19. Как создать поток демона в Java?
  20. Что такое ThreadLocal?
  21. Что такое группа тем? Почему его не рекомендуется использовать?
  22. Что такое дамп потока Java, как мы можем получить дамп потока Java программы?
  23. Что такое тупик? Как проанализировать и избежать тупиковой ситуации?
  24. Что такое класс таймера Java? Как запланировать запуск задачи через определенный интервал?
  25. Что такое пул потоков? Как мы можем создать пул потоков в Java?
  26. Что произойдет, если мы не переопределим метод run() класса Thread?

Вопросы для собеседования по Java Concurrency

  1. Что такое атомарная операция? Что такое атомарные классы в Java Concurrency API?
  2. Что такое интерфейс блокировки в Java Concurrency API? В чем его преимущества перед синхронизацией?
  3. Что такое Executors Framework?
  4. Что такое BlockingQueue? Как мы можем реализовать проблему «производитель-потребитель» с помощью очереди блокировки?
  5. Что такое Callable и Future?
  6. Что такое класс FutureTask?
  7. Что такое параллельные классы сбора?
  8. Что такое класс исполнителей?
  9. Какие улучшения в Concurrency API в Java 8?

Java Multithreading Interview Вопросы и ответы

В чем разница между процессом и потоком? Процесс — это автономная среда выполнения, и его можно рассматривать как программу или приложение, тогда как поток — это отдельная задача, выполняемая внутри процесса. Среда выполнения Java работает как единый процесс, который содержит различные классы и программы в качестве процессов. Thread можно назвать легковесным процессом. Поток требует меньше ресурсов для создания и существует в процессе, поток разделяет ресурсы процесса. Каковы преимущества многопоточного программирования? В многопоточном программировании несколько потоков выполняются одновременно, что повышает производительность, поскольку ЦП не простаивает, если какой-то поток ожидает получения некоторых ресурсов. Несколько потоков совместно используют память кучи, поэтому лучше создать несколько потоков для выполнения какой-либо задачи, а не создавать несколько процессов. Например, сервлеты лучше по производительности, чем CGI, потому что Servlet поддерживает многопоточность, а CGI — нет. В чем разница между потоком пользователя и потоком демона? Когда мы создаем поток в программе Java, он называется пользовательским потоком. Поток демона работает в фоновом режиме и не препятствует завершению работы JVM. Когда нет запущенных пользовательских потоков, JVM завершает работу программы и завершает работу. Дочерний поток, созданный из потока демона, также является потоком демона. Как мы можем создать поток в Java? Есть два способа создать Thread в Java: первый — реализовать интерфейс Runnable, а затем создать из него объект Thread, а второй — расширить класс Thread. Прочтите этот пост, чтобы узнать больше о создании потоков в java. Каковы различные состояния в жизненном цикле Thread?

When we create a Thread in java program, its state is New. Then we start the thread that change it's state to Runnable. Thread Scheduler is responsible to allocate CPU to threads in Runnable thread pool and change their state to Running. Other Thread states are Waiting, Blocked and Dead. Read this post to learn more about [life cycle of thread](/community/tutorials/thread-life-cycle-in-java-thread-states-in-java).

Можем ли мы вызвать метод run() класса Thread?

Yes, we can call run() method of a Thread class but then it will behave like a normal method. To actually execute it in a Thread, we need to start it using **Thread.start()** method.

Как мы можем приостановить выполнение потока на определенное время?

We can use Thread class sleep() method to pause the execution of Thread for certain time. Note that this will not stop the processing of thread for specific time, once the thread awake from sleep, it's state gets changed to runnable and based on thread scheduling, it gets executed.

Что вы понимаете о приоритете потока?

Every thread has a priority, usually higher priority thread gets precedence in execution but it depends on Thread Scheduler implementation that is OS dependent. We can specify the priority of thread but it doesn't guarantee that higher priority thread will get executed before lower priority thread. Thread priority is an _int_ whose value varies from 1 to 10 where 1 is the lowest priority thread and 10 is the highest priority thread.

Что такое планировщик потоков и разделение времени?

Thread Scheduler is the Operating System service that allocates the CPU time to the available runnable threads. Once we create and start a thread, it's execution depends on the implementation of Thread Scheduler. Time Slicing is the process to divide the available CPU time to the available runnable threads. Allocation of CPU time to threads can be based on thread priority or the thread waiting for longer time will get more priority in getting CPU time. Thread scheduling can't be controlled by java, so it's always better to control it from application itself.

Что такое переключение контекста в многопоточности?

Context Switching is the process of storing and restoring of CPU state so that Thread execution can be resumed from the same point at a later point of time. Context Switching is the essential feature for multitasking operating system and support for multi-threaded environment.

Как мы можем убедиться, что main() является последним потоком, который завершится в Java-программе?

We can use Thread join() method to make sure all the threads created by the program is dead before finishing the main function. Here is an article about [Thread join method](/community/tutorials/java-thread-join-example).

Как потоки взаимодействуют друг с другом?

When threads share resources, communication between Threads is important to coordinate their efforts. Object class wait(), notify() and notifyAll() methods allows threads to communicate about the lock status of a resource. Check this post to learn more about [thread wait, notify and notifyAll](/community/tutorials/java-thread-wait-notify-and-notifyall-example).

Почему методы связи потоков wait(), notify() и notifyAll() находятся в классе Object?

In Java every Object has a monitor and wait, notify methods are used to wait for the Object monitor or to notify other threads that Object monitor is free now. There is no monitor on threads in java and synchronization can be used with any Object, that's why it's part of Object class so that every class in java has these essential methods for inter thread communication.

Почему методы wait(), notify() и notifyAll() должны вызываться из синхронизированного метода или блока?

When a Thread calls wait() on any Object, it must have the monitor on the Object that it will leave and goes in wait state until any other thread call notify() on this Object. Similarly when a thread calls notify() on any Object, it leaves the monitor on the Object and other waiting threads can get the monitor on the Object. Since all these methods require Thread to have the Object monitor, that can be achieved only by synchronization, they need to be called from synchronized method or block.

Почему методы Thread sleep() и yield() являются статическими?

Thread sleep() and yield() methods work on the currently executing thread. So there is no point in invoking these methods on some other threads that are in wait state. That’s why these methods are made static so that when this method is called statically, it works on the current executing thread and avoid confusion to the programmers who might think that they can invoke these methods on some non-running threads.

Как мы можем добиться безопасности потоков в Java?

There are several ways to achieve thread safety in java - synchronization, atomic concurrent classes, implementing concurrent Lock interface, using volatile keyword, using immutable classes and Thread safe classes. Learn more at [thread safety tutorial](/community/tutorials/thread-safety-in-java).

Что такое ключевое слово volatile в Java

When we use volatile keyword with a variable, all the threads read it's value directly from the memory and don't cache it. This makes sure that the value read is the same as in the memory.

Что предпочтительнее - синхронизированный метод или синхронизированный блок?

Synchronized block is more preferred way because it doesn't lock the Object, synchronized methods lock the Object and if there are multiple synchronization blocks in the class, even though they are not related, it will stop them from execution and put them in wait state to get the lock on Object.

Как создать поток демона в Java?

Thread class setDaemon(true) can be used to create daemon thread in java. We need to call this method before calling start() method else it will throw IllegalThreadStateException.

Что такое ThreadLocal?

Java ThreadLocal is used to create thread-local variables. We know that all threads of an Object share it’s variables, so if the variable is not thread safe, we can use synchronization but if we want to avoid synchronization, we can use ThreadLocal variables. Every thread has its own ThreadLocal variable and they can use it gets () and set() methods to get the default value or change it’s value local to Thread. ThreadLocal instances are typically private static fields in classes that wish to associate the state with a thread. Check this post for small example program showing [ThreadLocal Example](/community/tutorials/java-threadlocal-example).

Что такое группа потоков? Почему не рекомендуется его использовать?

ThreadGroup is a class which was intended to provide information about a thread group. ThreadGroup API is weak and it doesn't have any functionality that is not provided by Thread. It has two main features - to get the list of active threads in a thread group and to set the uncaught exception handler for the thread. But Java 1.5 has added _setUncaughtExceptionHandler(UncaughtExceptionHandler eh)_ method using which we can add uncaught exception handler to the thread. So ThreadGroup is obsolete and hence not advised to use anymore.

```
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler(){

@Override
public void uncaughtException(Thread t, Throwable e) {
    System.out.println("exception occured:"+e.getMessage());
}
            
});
```

Что такое дамп потока Java, как мы можем получить дамп потока Java программы?

A thread dump is a list of all the threads active in the JVM, thread dumps are very helpful in analyzing bottlenecks in the application and analyzing deadlock situations. There are many ways using which we can generate Thread dump - Using Profiler, Kill -3 command, jstack tool, etc. I prefer jstack tool to generate thread dump of a program because it's easy to use and comes with JDK installation. Since it's a terminal-based tool, we can create a script to generate thread dump at regular intervals to analyze it later on. Read this post to know more about [generating thread dump in java](/community/tutorials/java-thread-dump-visualvm-jstack-kill-3-jcmd).

Что такое тупик? Как проанализировать и избежать тупиковой ситуации?

Deadlock is a programming situation where two or more threads are blocked forever, this situation arises with at least two threads and two or more resources. To analyze a deadlock, we need to look at the java thread dump of the application, we need to look out for the threads with state as BLOCKED and then the resources it’s waiting to lock, every resource has a unique ID using which we can find which thread is already holding the lock on the object. Avoid Nested Locks, Lock Only What is Required and Avoid waiting indefinitely are common ways to avoid deadlock situation, read this post to learn how to [analyze deadlock in java](/community/tutorials/deadlock-in-java-example) with a sample program.

Что такое класс таймера Java? Как запланировать выполнение задачи после указанного интервала?

java.util.Timer is a utility class that can be used to schedule a thread to be executed at a certain time in future. Java Timer class can be used to schedule a task to be run one-time or to be run at regular intervals. java.util.TimerTask is an **[abstract class](/community/tutorials/abstract-class-in-java "Abstract Class in Java with Example")** that implements Runnable interface and we need to extend this class to create our own TimerTask that can be scheduled using java Timer class. Check this post for [java Timer example](/community/tutorials/java-timer-timertask-example).

Что такое пул потоков? Как мы можем создать пул потоков в Java?

A thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to get executed. A thread pool manages the collection of Runnable threads and worker threads execute Runnable from the queue. java.util.concurrent.Executors provide implementation of java.util.concurrent.Executor interface to create the thread pool in java. [Thread Pool Example](/community/tutorials/threadpoolexecutor-java-thread-pool-example-executorservice) program shows how to create and use Thread Pool in java. Or read [ScheduledThreadPoolExecutor Example](/community/tutorials/java-scheduler-scheduledexecutorservice-scheduledthreadpoolexecutor-example) to know how to schedule tasks after certain delay.

Что произойдет, если мы не переопределим метод run() класса Thread?

Thread class run() method code is as shown below.

```
public void run() {
    if (target != null) {
        target.run();
    }
}
```

Above target set in the init() method of Thread class and if we create an instance of Thread class as `new TestThread()`, it's set to null. So nothing will happen if we don't override the run() method. Below is a simple example demonstrating this.

```
public class TestThread extends Thread {

	//not overriding Thread.run() method
	
	//main method, can be in other class too
	public static void main(String args[]){
		Thread t = new TestThread();
		System.out.println("Before starting thread");
		t.start();
		System.out.println("After starting thread");
	}
}
```

It will print only below output and terminate.

```
Before starting thread
After starting thread
```

Java Concurrency Interview Вопросы и ответы

Что такое атомарная операция? Что такое атомарные классы в Java Concurrency API? Атомарные операции выполняются в одном блоке задачи без вмешательства других операций. Атомарные операции необходимы в многопоточной среде, чтобы избежать несогласованности данных. int++ не является атомарной операцией. Таким образом, к тому времени, когда один поток прочитает свое значение и увеличит его на единицу, другой поток прочитает более старое значение, что приведет к неправильному результату. Чтобы решить эту проблему, нам нужно убедиться, что операция увеличения счетчика является атомарной, мы можем сделать это с помощью синхронизации, но Java 5 java.util.concurrent.atomic предоставляет классы-оболочки для int и long, которые можно использовать для достижения этого атомарно без использования синхронизации. Перейдите к этой статье, чтобы узнать больше об атомарных параллельных классах. Что такое интерфейс блокировки в Java Concurrency API? Каковы его преимущества перед синхронизацией? Интерфейс блокировки обеспечивает более обширные операции блокировки, чем можно получить с помощью синхронизированных методов и операторов. Они допускают более гибкое структурирование, могут иметь совершенно разные свойства и могут поддерживать несколько связанных объектов Condition. Преимущества замка в том, что можно сделать их справедливыми можно сделать поток реагирующим на прерывание во время ожидания объекта блокировки. можно попытаться получить блокировку, но вернуться сразу или после тайм-аута, если блокировка не может быть получена можно получать и снимать блокировки в разных объемах и в разных порядках Подробнее читайте в примере блокировки Java. Что такое Executors Framework? В Java 5 среда Executor была представлена с интерфейсом java.util.concurrent.Executor. Платформа Executor — это платформа для стандартизации вызова, планирования, выполнения и управления асинхронными задачами в соответствии с набором политик выполнения. Создание большого количества потоков без ограничения максимального порога может привести к тому, что приложению не хватит памяти кучи. Таким образом, создание ThreadPool является лучшим решением, поскольку конечное число потоков может быть объединено и повторно использовано. Инфраструктура Executors упрощает процесс создания пулов потоков в java. Прочтите этот пост, чтобы изучить пример кода для создания пула потоков с использованием платформы Executors. Что такое BlockingQueue? Как мы можем реализовать проблему «производитель-потребитель» с помощью очереди блокировки? java.util.concurrent.BlockingQueue — это очередь, которая поддерживает операции, ожидающие, пока очередь не станет непустой при извлечении и удалении элемента, и ожидающие освобождения места в очереди при добавлении элемента. BlockingQueue не принимает нулевые значения и генерирует исключение NullPointerException, если вы пытаетесь сохранить нулевое значение в очереди. Реализации BlockingQueue потокобезопасны. Все методы организации очередей являются атомарными по своей природе и используют внутренние блокировки или другие формы контроля параллелизма. Интерфейс BlockingQueue является частью среды коллекций Java и в основном используется для реализации проблемы производитель-потребитель. Проверьте этот пост для реализации проблемы производитель-потребитель с использованием BlockingQueue. Что такое Callable и Future?

Java 5 introduced java.util.concurrent.Callable interface in concurrency package that is similar to Runnable interface but it can return any Object and able to throw Exception. The Callable interface uses Generics to define the return type of Object. Executors class provide useful methods to execute Callable in a thread pool. Since callable tasks run in parallel, we have to wait for the returned Object. Callable tasks return java.util.concurrent.Future object. Using Future we can find out the status of the Callable task and get the returned Object. It provides the get() method that can wait for the Callable to finish and then return the result. Check this post for [Callable Future Example](/community/tutorials/java-callable-future-example).

Что такое класс FutureTask?

FutureTask is the base implementation class of Future interface and we can use it with Executors for asynchronous processing. Most of the time we don't need to use FutureTask class but it comes real handy if we want to override some of the methods of Future interface and want to keep most of the base implementation. We can just extend this class and override the methods according to our requirements. Check out **[Java FutureTask Example](/community/tutorials/java-futuretask-example-program "Java FutureTask Example Program")** post to learn how to use it and what are different methods it has.

Что такое параллельные классы сбора?

Java Collection classes are fail-fast which means that if the Collection will be changed while some thread is traversing over it using iterator, the iterator.next() will throw ConcurrentModificationException. Concurrent Collection classes support full concurrency of retrievals and adjustable expected concurrency for updates. Major classes are ConcurrentHashMap, CopyOnWriteArrayList and CopyOnWriteArraySet, check this post to learn [how to avoid ConcurrentModificationException when using iterator](/community/tutorials/java-util-concurrentmodificationexception).

Что такое класс исполнителей?

Executors class provide utility methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes. Executors class can be used to easily create Thread Pool in java, also this is the only class supporting execution of Callable implementations.

Какие улучшения в Concurrency API в Java 8?

Some important concurrent API enhancements are:

-   ConcurrentHashMap compute(), forEach(), forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() and search() methods.
-   CompletableFuture that may be explicitly completed (setting its value and status).
-   Executors newWorkStealingPool() method to create a work-stealing thread pool using all available processors as its target parallelism level.

**Recommended Read**: [Java 8 Features](/community/tutorials/java-8-features-with-examples "Java 8 Features for Developers – lambdas, Functional interface, Stream and Time API")

Это все, что касается вопросов для собеседования по Java Thread и Concurrency, я добавляю новые в этот список. Так что добавьте пост в закладки для дальнейшего использования.