Multi-threading and concurrency issues is one of the questions that interviewers prefer to ask in Java technology interviews. Here, most of the important issues are listed from the perspective of the interview, but you should still have a solid grasp of the basics of Java multithreading to cope with future problems.
JavaMultithreaded Interview Question
1 What is the difference between a process and a thread?
A process is a self contained environment that can be thought of as a program or an application. A thread is a task that is executed in a process. The Java runtime environment is a single process that contains different classes and programs. A thread can be called a lightweight process. Threads require fewer resources to create and reside in a process, and can share resources in a process.
2 What are the benefits of multithreaded programming?
In a multi-threaded program, multiple threads are executed concurrently to increase the efficiency of the program. The CPU does not enter an idle state because a thread needs to wait for resources. Multiple threads share heap memory, so creating multiple threads to perform some tasks is better than creating multiple processes. For example, Servlets are better than CGI because Servlets support multithreading and CGI does not. What is the difference between
3, user thread and daemon thread?
When we create a thread in a Java program, it is called a user thread. A daemon thread is a thread that executes in the background and does not prevent the JVM from terminating. When no user thread is running, the JVM closes the program and exits. The child thread created by a daemon thread is still a daemon thread.
4, how do we create a thread?
There are two ways to create a thread: one is to implement the Runnable interface, and then pass it to the Thread constructor to create a Thread object; the second is to directly inherit the Thread class. If you want to know more, you can read this article on how to create threads in Java.
5, what are the different thread life cycles?
When we create a new thread in a Java program, its state is New. When we call the thread's start() method, the state is changed to Runnable. The thread scheduler allocates CPU time for threads in the Runnable thread pool and changes their state to Running. Other thread states are Waiting, Blocked, and Dead. Read this article to learn more about the thread life cycle.
6, can you directly call the run() method of the Thread class?
Of course, but if we call Thread's run() method, it will behave the same as the normal method. In order to execute our code in a new thread, we must use the Thread.start() method.
7, how do I pause a running thread for a while?
We can use the Sleep() method of the Thread class to pause the thread for a while. It should be noted that this does not cause the thread to terminate. Once the thread is woken up from hibernation, the state of the thread will be changed to Runnable, and according to the thread scheduling, it will be executed.
8, what is your understanding of thread priority?
Every thread has priority. In general, high-priority threads have priority at runtime, but this depends on the implementation of thread scheduling, which is related to the operating system (OS). Dependent). We can define the priority of a thread, but this does not guarantee that a high-priority thread will execute before a low-priority thread. The thread priority is an int variable (from 1-10), with 1 being the lowest priority and 10 being the highest priority.
9, what is Thread Scheduler and Time Slicing? The
thread scheduler is an operating system service that is responsible for allocating CPU time for threads in the Runnable state. Once we create a thread and start it, its execution depends on the implementation of the thread scheduler. Time slicing is the process of allocating available CPU time to available Runnable threads. The allocation of CPU time can be based on thread priority or the time the thread waits. Thread scheduling is not controlled by the Java virtual machine, so it is a better choice to control it by the application (that is, don't let your program depend on the thread's priority).
10, in multithreading, what is context-switching?
Context switching is the process of storing and restoring CPU state, which enables thread execution to resume execution from the point of interruption. Context switching is a fundamental feature of multitasking operating systems and multi-threaded environments.
11, how do you ensure that the thread where the main() method is located is the last thread of the Java program?
We can use the joint() method of the Thread class to ensure that threads created by all programs end before the main() method exits. Here is an article about the joint() method of the Thread class.
12, how do you communicate between threads?
When inter-thread sharing is a resource, inter-thread communication is an important means of coordinating them. The wait()\notify()\notifyAll() method in the Object class can be used to communicate the state of the lock on a resource between threads. Click here for more on threads wait, notify, and notifyAll.
13. Why are thread communication methods wait(), notify(), and notifyAll() defined in the Object class?
Every object in Java has a lock (monitor, which can also be a monitor) and methods such as wait() and notify() are used to wait for the object's lock or to notify other thread object's monitors. There are no locks and synchronizers available to any object in the Java thread. This is why these methods are part of the Object class, so that every class in Java has a basic method for inter-thread communication
14, why wait(), notify(), and notifyAll() must be in synchronous methods or synchronous. Is it called in the block?
When a thread needs to call the object's wait() method, the thread must have the object's lock, then it will release the object lock and enter the wait state until other threads call the notify() on the object. method. Similarly, when a thread needs to call the object's notify() method, it releases the object's lock so that other waiting threads can get the object lock. Since all of these methods require the thread to hold the lock on the object, this can only be done by synchronization, so they can only be called in the synchronization method or sync block.
15, Why are the sleep() and yield() methods of the Thread class static? The sleep() and yield() methods of the
Thread class will run on the currently executing thread. So it doesn't make sense to call these methods on other threads that are in a wait state. This is why these methods are static. They can work in the thread that is currently executing, and avoid programmers mistakenly thinking that these methods can be called on other non-running threads.
16, how to ensure thread safety?
There are many ways to ensure thread safety in Java - synchronization, using atomic classes, implementing concurrent locks, using the volatile keyword, using invariant classes and thread-safe classes. You can learn more in the thread safety tutorial.
17, What is the role of the volatile keyword in Java?
When we use the volatile keyword to decorate a variable, the thread will read the variable directly and not cache it. This ensures that the variables read by the thread are consistent with those in memory.
18, synchronization method and sync block, which is a better choice? The
sync block is a better choice because it doesn't lock the entire object (of course you can also lock it around the object). The synchronization method locks the entire object, even if there are multiple unrelated sync blocks in the class, which usually causes them to stop executing and wait for the lock on the object.
19, how to create a daemon thread?
Use the setDaemon(true) method of the Thread class to set the thread as a daemon thread. Note that you need to call this method before calling the start() method, otherwise an IllegalThreadStateException will be thrown.
20, what is ThreadLocal?
ThreadLocal is used to create local variables of threads. We know that all threads of an object share its global variables, so these variables are not thread-safe. We can use synchronization technology. . But when we don't want to use synchronization, we can choose the ThreadLocal variable.
Each thread will have its own Thread variable, which can use the get()\set() method to get their default value or change their value inside the thread. ThreadLocal instances are usually private static properties that are expected to be associated with the thread state. In the ThreadLocal example, you can see a small program about ThreadLocal.
21, what is a Java thread dump (Thread Dump), how to get it?
Thread dump is a list of JVM active threads that are useful for analyzing system bottlenecks and deadlocks. There are many ways to get thread dumps - using Profiler, Kill -3 commands, jstack tools, and more. I prefer the jstack tool because it's easy to use and comes with the JDK. Since it is a terminal-based tool, we can write some scripts to generate thread dumps for analysis. Read this document to learn more about generating thread dumps.
22, what is deadlock? How to analyze and avoid deadlocks?
Deadlock refers to the situation where more than two threads are blocked forever. This situation requires at least two threads and more than two resources.
Analyzing deadlocks, we need to look at the thread dump of the Java application. We need to find out which threads are BLOCKED and what resources they are waiting for. Each resource has a unique id, and with this id we can find out which thread already has its object lock.
Avoid nested locks, use locks only where needed and avoid indefinite waits is the usual way to avoid deadlocks. Read this article to learn how to analyze deadlocks.
23, what is the Java Timer class? How do I create a task with a specific time interval?
java.util.Timer is a utility class that can be used to schedule a thread to execute at a specific time in the future. The Timer class can be used to schedule one-time tasks or periodic tasks.
java.util.TimerTask is an abstract class that implements the Runnable interface. We need to inherit this class to create our own timed tasks and use Timer to schedule its execution.
There is an example of java Timer here.
24, what is a thread pool? How to create a Java thread pool?
A thread pool manages a set of worker threads, and it also includes a queue for placing tasks waiting to be executed.
java.util.concurrent.Executors provides an implementation of the java.util.concurrent.Executor interface for creating thread pools. The thread pool example shows how to create and use a thread pool, or read the ScheduledThreadPoolExecutor example to learn how to create a periodic task.
Java concurrent interview question
1, what is atomic operation? What are the atomic classes in the Java Concurrency API? The
atomic operation refers to an operational task unit that is not affected by other operations. Atomic operations are a must for avoiding data inconsistencies in a multi-threaded environment.
int++ is not an atomic operation, so when a thread reads its value and increments by 1, another thread may read the previous value, which raises an error.
In order to solve this problem, we must ensure that the increase operation is atomic. Before JDK1.5, we can use synchronization technology to do this. To JDK 1.5, the java.util.concurrent.atomic package provides int and long types of wrappers that automatically guarantee that their operations are atomic and do not require synchronization. You can read this article to learn about the atomic class of Java.
2, What is the Lock interface in the Java Concurrency API? What are the advantages of comparing synchronization? The
Lock interface provides a more scalable lock operation than the synchronization method and sync block. They allow for a more flexible structure, can have completely different properties, and can support conditional objects of multiple related classes.
Its advantages are:
can make the lock more fair
can make the thread respond to the interrupt when waiting for the lock
can let the thread try to acquire the lock, and when the lock cannot be obtained Return immediately or wait for a while
can get and release locks in different orders in different orders
Read more about lock examples
3, what is the Executors framework? The
Executor framework was introduced in Java 5 with the java.util.concurrent.Executor interface. The Executor framework is a framework for asynchronous tasks that are invoked, scheduled, executed, and controlled based on a set of execution policies.
Unlimited creation of threads can cause application memory overflow. So creating a thread pool is a better solution because you can limit the number of threads and recycle them. Using the Executors framework makes it easy to create a thread pool. Read this article to learn how to create a thread pool using the Executor framework.
4, what is the blocking queue? How do you use a blocking queue to implement a producer-consumer model?
java.util.concurrent.BlockingQueue is characterized by: when the queue is empty, the operation of getting or deleting elements from the queue will be blocked, or when the queue is full, adding elements to the queue Will be blocked.
The blocking queue does not accept null values, it throws a NullPointerException when you try to add a null value to the queue.
The implementation of blocking queues is thread-safe. All query methods are atomic and use internal locks or other forms of concurrency control. The
BlockingQueue interface is part of the java collections framework and is primarily used to implement producer-consumer issues.
Read this article to learn how to use the blocking queue to implement producer-consumer issues.
5, What is Callable and Future?
Java 5 Introduced the java.util.concurrent.Callable interface in the concurrency package, which is similar to the Runnable interface, but it can return an object or throw a abnormal. The
Callable interface uses generics to define its return type. The Executors class provides some useful ways to perform tasks within a Callable in a thread pool. Since the Callable task is parallel, we have to wait for the result it returns. The java.util.concurrent.Future object solves this problem for us. After the thread pool submits the Callable task, it returns a Future object. Using it, we can know the state of the Callable task and get the execution result returned by Callable. Future provides a get() method that allows us to wait for the Callable to end and get its execution results.
Read this article to learn more about Callable, Future examples.
6, What is FutureTask?
FutureTask is a basic implementation of Future, we can use it to process asynchronous tasks with Executors. Usually we don't need to use the FutureTask class, it becomes very useful when we intend to rewrite some methods of the Future interface and keep the original implementation. We can just inherit from it and rewrite the methods we need. Read the Java FutureTask example and learn how to use it.
7, what is the implementation of concurrent containers?
Java collection classes are fast failing, which means that when the collection is changed and a thread is traversing the collection using an iterator, the iterator's next() method will throw a ConcurrentModificationException. The
concurrent container supports concurrent traversal and concurrent updates.
The main classes are ConcurrentHashMap, CopyOnWriteArrayList and CopyOnWriteArraySet. Read this article to learn how to avoid ConcurrentModificationException.
8, What is the Executors class?
Executors provides some tool methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory and Callable classes.
Executors can be used to easily create thread pools.
Welcome to the Java Advanced Architecture Learning Exchange Group: 375989619 This group provides free study guides and free answers. If you don't understand the problem, you can have career planning and interview guidance after the group is proposed. Into the group to modify the group Note: Development period - region - experience Convenient architect to answer questions Receive a full set of architect video for free! ! ! ! ! ! ! !