English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

50 Java Thread Interview Questions (Classic)

Below are some popular interview questions related to Java threads, which you can use to prepare well for the interview.

1What is a thread?

A thread is the smallest unit of computation scheduling that an operating system can perform, which is contained within a process and is the actual operating unit of the process. Programmers can use it for multiprocessor programming, and you can use multithreading to speed up computation-intensive tasks. For example, if it takes 100 milliseconds, then it only takes 10 milliseconds. Java provides excellent support for multithreading at the language level, which is also a good selling point. For more detailed information, please click here.

2What is the difference between threads and processes?

A thread is a subset of a process. A process can have many threads, and each thread executes different tasks in parallel. Different processes use different memory spaces, while all threads share the same memory space. Do not confuse it with stack memory, as each thread has its own stack memory used to store local data. More detailed information can be found by clicking here.

3How to implement a thread in Java?

There are two ways at the language level. An instance of java.lang.Thread is a thread, but it needs to call the java.lang.Runnable interface to execute. Since the thread class itself calls the Runnable interface, you can inherit java.lang.Thread or directly call the Runnable interface to override the run() method to implement a thread. More detailed information can be found by clicking here.

4Use Runnable or Thread?

This question is a follow-up to the previous one. Everyone knows that we can implement threads by inheriting the Thread class or calling the Runnable interface. The question is, which method is better, and when should it be used? This question is easy to answer, if you know that Java does not support multiple inheritance of classes but allows multiple interface calls. So if you want to inherit other classes, it is better to call the Runnable interface. More detailed information can be found by clicking here.

6What are the differences between start() and run() methods in Thread class?

This question is often asked, but it can still distinguish the interviewee's understanding of the Java thread model. The start() method is used to start a newly created thread, and the start() method internally calls the run() method, which is different from calling run() directly. When you call the run() method, it will only be called in the original thread, and no new thread will be started. The start() method will start a new thread. More discussions can be found by clicking here

7What are the differences between Runnable and Callable in Java?

Runnable and Callable both represent tasks that need to be executed in different threads. Runnable was introduced in JDK10, Callable was introduced in JDK1.5 They have been added. The main difference between them is that the call() method of Callable can return a value and throw an exception, while the run() method of Runnable does not have these features. Callable can return a Future object that contains the computed result. More detailed explanations can be found in my blog.

8What are the differences between CyclicBarrier and CountDownLatch in Java?

Both CyclicBarrier and CountDownLatch can be used to make a group of threads wait for other threads. Unlike CyclicBarrier, CountdownLatch cannot be reused. Click here for more information and example code.

9What is the Java memory model?

The Java memory model specifies and guides the deterministic behavior of Java programs across different memory architectures, CPUs, and operating systems. It is particularly important in multi-threaded scenarios. The Java memory model guarantees that changes made by one thread can be seen by other threads, providing a happens-before relationship between them. This relationship defines some rules that make the programmer's thought process clearer in concurrent programming. For example, the happens-before relationship ensures that:

The code within a thread can be executed in the order of occurrence, which is called the program order rule.

For the same lock, an unlock operation must occur before another locking operation that happens later in time, also known as the monitor locking rule.

The write operation to a volatile variable must occur before the read operation to the next volatile variable, also known as the volatile variable rule.

Any operation within a thread must be after the thread's start() call, also known as the thread start rule.

All operations of a thread must be before the thread terminates, also known as the thread termination rule.

The finalization operation of an object must be after the object is constructed, also known as the object finalization rule.

Transitivity

I strongly recommend that you read Chapter 16 of 'Java Concurrency in Practice' to deepen your understanding of the Java memory model.

10What is a volatile variable in Java?

volatile is a special modifier that can only be used for member variables. In the absence of synchronized classes in Java concurrent programs, the operations of multiple threads on member variables are transparent to other threads. volatile variables can ensure that the next read operation occurs after the previous write operation, which is the rule of the volatile variable in the previous question. Click here to view more information about volatile.

11What is thread safety? Is Vector a thread-safe class? (See here)

If multiple threads are running simultaneously in the process where your code is located, and these threads may run this code concurrently, it is thread-safe if the result of each run is the same as that of a single-threaded run, and the values of other variables are also as expected. This is called thread safety. A single instance object of a thread-safe counter class will not experience calculation errors when used by multiple threads. It is obvious that you can divide collection classes into two groups: thread-safe and non-thread-safe. Vector implements thread safety through synchronized methods, while ArrayList is not thread-safe.

12What is a race condition in Java? Give an example to illustrate.

Race conditions can cause some bugs to appear in programs under concurrent conditions. When multiple threads compete for some resources, race conditions occur. If the program to be executed first fails in the competition and is executed later, the entire program will appear some uncertain bugs. These bugs are difficult to find and will repeat because of the random competition between threads. An example is unordered processing, see the answer for details.

13How to stop a thread in Java?

Java provides a rich API but does not provide an API for stopping threads. JDK 1.0 There were some control methods like stop(), suspend(), and resume() in the past, but due to potential deadlock threats, they were deprecated in subsequent JDK versions. After that, Java API designers did not provide a compatible and thread-safe method to stop a thread. A thread will automatically end when the run() or call() method is executed. If you want to manually end a thread, you can use a volatile boolean variable to exit the loop in the run() method or cancel the task to interrupt the thread. Click here to view the example code.

14What will happen if an exception occurs while a thread is running?

This is a very tricky Java interview question I encountered in an interview. In short, if an exception is not caught, the thread will stop executing.

Thread.UncaughtExceptionHandler is an embedded interface used to handle situations where threads are suddenly interrupted by uncaught exceptions. When an uncaught exception will cause a thread to be interrupted, the JVM will use Thread.getUncaughtExceptionHandler() to query the thread's UncaughtExceptionHandler and pass the thread and exception as parameters to the handler's uncaughtException() method for processing.

15How to share data between two threads?

You can achieve this purpose by sharing objects, or by using concurrent data structures like blocking queues. This tutorial 'Java Inter-thread Communication' (involving sharing objects between two threads) implements the producer-consumer model using the wait and notify methods.

16What is the difference between notify and notifyAll in Java?

This is another tricky question because multi-threading can wait for a single monitor lock. Java API designers have provided some methods to notify them when the waiting condition changes, but these methods are not fully implemented. The notify() method cannot wake up a specific thread, so it is only useful when only one thread is waiting. The notifyAll() method wakes up all threads and allows them to compete for the lock, ensuring that at least one thread can continue to run. My blog has more detailed information and example code.

17Why are the methods wait, notify, and notifyAll not in the Thread class?

This is a design-related question that examines the interviewee's views on existing systems and some universally existing but seemingly unreasonable things. When answering these questions, you should explain why it is meaningful to put these methods in the Object class, as well as the reasons not to put them in the Thread class. A very obvious reason is that the locks provided by JAVA are object-level rather than thread-level, and each object has a lock that is obtained through the thread. If the thread needs to wait for certain locks, it makes sense to call the wait() method in the object. If the wait() method is defined in the Thread class, it is not clear which lock the thread is waiting for. In short, since wait, notify, and notifyAll are lock-level operations, they are defined in the Object class because locks belong to objects. You can also check this article for more information.

18What is a ThreadLocal variable?

ThreadLocal is a special variable in Java. Each thread has its own ThreadLocal, which means each thread has its own independent variable, completely eliminating the competition condition. It is a good method to create expensive objects in a thread-safe manner, such as using ThreadLocal to make SimpleDateFormat thread-safe, because this class has a high cost of creation and needs to create a different instance each time it is called, so it is not worth using it in a local scope. If each thread is provided with its own unique variable copy, it will greatly improve efficiency. First, the cost of creating expensive objects is reduced by reuse. Second, you obtain thread safety without using high-cost synchronization or immutability. Another good example of thread-local variables is ThreadLocalRandom, which reduces the number of expensive Random object creations in a multi-threaded environment. Check the answer for more information.

19What is FutureTask?

In Java concurrent programs, FutureTask represents an asynchronous computation that can be canceled. It has methods to start and cancel the computation, check if the computation is complete, and retrieve the computation result. The result can only be retrieved when the computation is completed; if the computation has not yet been completed, the get method will block. A FutureTask object can wrap an object that has called Callable and Runnable, as FutureTask also implements the Runnable interface, so it can be submitted to an Executor for execution.

20) What is the difference between the interrupted and isInterrupted methods in Java?

The main difference between interrupted() and isInterrupted() is that the former clears the interrupt status while the latter does not. Java's multi-threading interrupt mechanism is implemented using internal flags. Calling Thread.interrupt() to interrupt a thread sets the interrupt flag to true. When an interrupted thread calls the static method Thread.interrupted() to check the interrupt status, the interrupt status is reset to zero. The non-static method isInterrupted() is used to query the interrupt status of other threads and does not change the interrupt status flag. In simple terms, any method that throws an InterruptedException exception will reset the interrupt status. Regardless, a thread's interrupt status may be changed by other threads by calling interrupt() to change it.

21Why should the wait and notify methods be called within a synchronized block?

This is mainly because the Java API strictly requires it, and if you do not do so, your code will throw an IllegalMonitorStateException exception. Another reason is to avoid race conditions between wait and notify.

22) Why should you check the waiting condition in a loop?63;

A thread in a waiting state may receive incorrect alerts and pseudo-wakeups. If the waiting condition is not checked within a loop, the program may exit without satisfying the end condition. Therefore, when a waiting thread wakes up, it cannot be assumed that its original waiting state is still valid. During this period between the call to notify() and the waking up of the waiting thread, it may change. This is why using the wait() method in a loop is more effective. You can try creating a template call to wait and notify in Eclipse. If you want to learn more about this issue, I recommend reading the chapter on threads and synchronization in 'Effective Java'.

23) What are the differences between synchronized collections and concurrent collections in Java?

Both synchronized collections and concurrent collections provide appropriate thread-safe collections for multi-threading and concurrency, but concurrent collections have higher scalability. In Java1.5 Previously, programmers only had synchronized collections to use, and during multi-threaded concurrency, they would cause contention, hindering the scalability of the system. Java5 The introduction of concurrent collections like ConcurrentHashMap, which not only provides thread safety but also improves scalability with modern technologies such as lock separation and internal partitioning. For more information, please refer to the answer.

24What are the differences between the heap and stack in Java?

Why is this question categorized under multi-threading and concurrency interview questions? Because the stack is a memory area closely related to threads. Each thread has its own stack memory, used to store local variables, method parameters, and stack calls. Variables stored in one thread are invisible to other threads. The heap is a shared public memory area for all threads. Objects are created in the heap, and to improve efficiency, threads will cache one from the heap into their own stack. If multiple threads use the same variable, it may cause problems, and that's when volatile variables can come into play, requiring threads to read the variable's value from the main memory.

For more information, please refer to the answer.

25What is a thread pool? Why should it be used?

Creating threads consumes expensive resources and time. If threads are created only when tasks arrive, the response time will increase, and the number of threads a process can create is limited. To avoid these problems, several threads are created at program startup to respond to processing, which are called thread pools, and the threads inside are called worker threads. From JDK1.5 At the beginning, the Java API provides the Executor framework to allow you to create different thread pools. For example, a single-threaded pool processes one task at a time; a thread pool with a fixed number of threads or a cache thread pool (an scalable thread pool suitable for many short-lived tasks). For more information, please refer to this article.

26How do you write code to solve the producer-consumer problem?

In reality, many thread problems you solve are related to the producer-consumer model, where one thread produces tasks for other threads to consume. You must know how to communicate between threads to solve this problem. A lower-level method is to use wait and notify to solve this problem, while a more commendable method is to use Semaphore or BlockingQueue to implement the producer-consumer model. This tutorial includes an implementation of it.

27How do you avoid deadlock?

Deadlock in Java multithreading

Deadlock refers to a phenomenon where two or more processes, during execution, cause each other to wait due to resource contention. Without external intervention, they will not be able to proceed. This is a serious problem because deadlock can cause your program to hang and fail to complete tasks. The occurrence of deadlock must meet the following four conditions:

Mutual exclusion condition: A resource can only be used by one process at a time.

Request and hold condition: When a process is blocked due to a resource request, it holds onto the resources it has already obtained.

Non-preemption condition: A process that has obtained a resource cannot be forcibly preempted before it is fully used.

Circular waiting condition: A set of processes form a circular waiting relationship for resources, where the head and tail are connected.

The simplest way to avoid deadlock is to prevent circular waiting conditions, set flags for all resources in the system, sort them, and stipulate that all processes must apply for resources in a certain order (ascending or descending) to avoid deadlock. This tutorial includes code examples and detailed discussions on avoiding deadlock.

28What are the differences between livelock and deadlock in Java?

This is an extension of the previous question. Livelock is similar to deadlock, but the difference is that the state of a thread or process in a livelock is constantly changing. Livelock can be considered a special form of starvation. A real-world example of livelock is two people meeting in a narrow corridor, both trying to let the other pass by, but because they are avoiding in the same direction, neither can pass through the corridor. In simple terms, the main difference between livelock and deadlock is that the state of the former can change but cannot continue to execute.

29How do you detect whether a thread holds a lock?

I never knew we could detect whether a thread holds a lock until I participated in a phone interview. There is a method called holdsLock() in java.lang.Thread, which returns true if and only if the current thread holds the lock of a specific object. You can read this article for more information.

30) How do you get the thread stack in Java?

For different operating systems, there are various methods to obtain the thread stack of a Java process. When you obtain the thread stack, the JVM will store the state of all threads in a log file or output it to the console. In Windows, you can use Ctrl + Press the Break key combination to get the thread stack, and use kill under Linux. -3 command. You can also use the jstack tool to get it, which operates on thread id, and you can use the jps tool to find the id.

31Which parameter in JVM is used to control the stack size of threads?

This question is very simple, -The Xss parameter is used to control the stack size of threads. You can view the JVM configuration list for more information about this parameter.

32What are the differences between synchronized and ReentrantLock in Java?

For a long time, Java could only implement mutual exclusion through the synchronized keyword, which has some drawbacks. For example, you cannot expand methods or block boundaries outside of locks, or cancel the lock acquisition halfway, etc. Java 5 The Lock interface provides more complex control to solve these problems. The ReentrantLock class implements Lock, which has the same concurrency and memory semantics as synchronized and also has scalability. You can read this article for more information.

33There are three threads T1, T2, T3How to ensure they execute in order?

There are many ways to make threads execute in a specific order in multi-threading. You can use the join() method of the Thread class to start another thread in one thread, and the other thread completes before the current thread continues to execute. To ensure the order of three threads, you should start the last one (T3 invokes T2, T2 invokes T1This is to ensure that T1 will complete first while T3 The final completion. You can read this article for more information.

34What is the role of the yield method in Thread class?

The Yield method can pause the currently executing thread object, allowing other threads with the same priority to execute. It is a static method and only guarantees that the current thread gives up CPU usage but does not guarantee that other threads will definitely use CPU. The thread that executes yield() may be executed again immediately after entering the suspended state. Click here to view more information about the yield method.

35What is the concurrency level of ConcurrentHashMap in Java?

ConcurrentHashMap divides the actual map into several parts to achieve its scalability and thread safety. This division is obtained using the concurrency level, which is an optional parameter of the ConcurrentHashMap class constructor, with a default value of 16This can avoid contention in a multi-threaded scenario. For more information on concurrency and internal size adjustment, please read my article 'How ConcurrentHashMap works in Java'.

36What is Semaphore in Java?

In Java, Semaphore is a new synchronization class that is a counting signal. Conceptually, it maintains a set of permits. Each acquire() will be blocked before the permit is available, and then the permit is obtained. Each release() adds a permit, which may release a blocked acquirer. However, Semaphore only counts the number of available permits without using actual permit objects and takes corresponding actions. Semaphores are often used in multi-threaded code, such as database connection pools. More detailed information can be found by clicking here.

37) What will happen if the thread pool queue is full when you submit a task?

This question is quite cunning. Many programmers might think that the task will be blocked until there is a free slot in the thread pool queue. In fact, if a task cannot be scheduled for execution, the submit() method of ThreadPoolExecutor will throw a RejectedExecutionException exception.

38) What is the difference between the submit() and execute() methods in Java thread pools?

Both methods can submit tasks to a thread pool. The return type of the execute() method is void, which is defined in the Executor interface, while the submit() method can return a Future object holding the computation result, which is defined in the ExecutorService interface, which extends the Executor interface. Other thread pool classes like ThreadPoolExecutor and ScheduledThreadPoolExecutor all have these methods. More detailed information can be found by clicking here.

39) What is a blocking method?

Blocking methods refer to the situation where the program will wait for the completion of the method without doing anything else, such as the accept() method of ServerSocket, which keeps waiting for a client connection. Here, blocking refers to the suspension of the current thread until the result is obtained before returning, before the call result is returned. In addition, there are asynchronous and non-blocking methods that return before the task is completed. More detailed information can be found by clicking here.

40) Is Swing thread-safe? Why?

You can confidently give an answer that Swing is not thread-safe, but you should explain the reason for this answer even if the interviewer does not ask why. When we say Swing is not thread-safe, we often mention its components, which cannot be modified in a multi-threaded environment. All updates to GUI components must be completed in the AWT thread, while Swing provides both synchronous and asynchronous callback methods for updates. Click here to view more information about Swing and thread safety.

41) What are the differences between invokeAndWait and invokeLater in Java?

These two methods are provided by the Swing API for Java developers to update GUI components from the current thread instead of the event dispatch thread. InvokeAndWait() synchronously updates GUI components, such as a progress bar. Once the progress is updated, the progress bar also needs to make corresponding changes. If the progress is tracked by multiple threads, then the invokeAndWait() method is called to request the event dispatch thread to update the component accordingly. The invokeLater() method is an asynchronous call to update the component. More detailed information can be found by clicking here.

42) What methods in the Swing API are thread-safe?

This question also mentions swing and thread safety. Although components are not thread-safe, there are some methods that can be safely called by multi-threading, such as repaint(), revalidate(). The setText() method of JTextComponent and the insert() and append() methods of JTextArea are also thread-safe.

43) How to create an Immutable object in Java?

This question seems to have nothing to do with multi-threading, but immutability helps simplify the already complex concurrent programs. Immutable objects can be shared without synchronization, reducing the overhead of synchronization when accessing the object concurrently. However, Java does not have the @Immutable annotation. To create an immutable class, you need to follow several steps: initialize all members through the constructor, do not provide setter methods for variables, declare all members as private so that they cannot be accessed directly, and in the getter methods, do not return the object itself directly, but clone the object and return a copy of the object. My article 'how to make an object Immutable in Java' has a detailed tutorial, and after reading it, you can be confident.

44What is ReadWriteLock in Java?

Generally speaking, read-write locks are the results of the lock separation technology used to improve the performance of concurrent programs. In Java, ReadWriteLock is a feature of Java 5 a new interface added, a ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for write. In the absence of write threads, a read lock may be held by multiple read threads at the same time. The write lock is exclusive, and you can use the ReentrantReadWriteLock in JDK to implement this rule, which supports at most 65535 write locks and 65535 read locks.

45What is busy-waiting in multi-threading?63;

Busy-waiting is when programmers use a loop to make a thread wait, unlike traditional methods wait(), sleep(), or yield(), all of which give up CPU control, while busy-waiting does not give up CPU control, it is just running an empty loop. The purpose of doing this is to retain CPU cache, in a multi-core system, when a waiting thread wakes up, it may run on another core, which will rebuild the cache. To avoid rebuilding the cache and reducing the time to rebuild the cache, it can be used. You can read this article for more information.

46What are the differences between volatile variables and atomic variables?

This is an interesting question. First of all, volatile variables and atomic variables look very similar, but their functions are different. Volatile variables can ensure the happens-before relationship, that is, write operations will occur before subsequent read operations, but they cannot ensure atomicity. For example, if the count variable is declared as volatile, then count++ operations are not atomic. The atomic methods provided by the AtomicInteger class can make such operations atomic, such as the getAndIncrement() method performs atomic increment operations by adding one to the current value, other data types and reference variables can also perform similar operations.

47What will happen if the thread in the synchronized block throws an exception?

This question has坑 many Java programmers, and if you can think of the lock release line to answer, there is still a chance to answer correctly. Whether your synchronized block exits normally or abnormally, the thread inside will release the lock, so I prefer synchronized block than lock interface, because it doesn't require me to spend energy to release the lock, this feature can be realized by releasing the lock in the finally block.

48What is the double-checked locking of the Singleton pattern?

This question is often asked in Java interviews, but the interviewer's satisfaction with the answer to this question is only 50%. Half of the people can't write the double-checked locking, and half of them can't say its hidden dangers and Java1.5 How to correct it. It is actually an old method used to create a thread-safe singleton. When the singleton instance is created for the first time, it tries to use a single lock for performance optimization, but it is too complex in JDK1.4 In it, it is a failure, and I personally don't like it either. Regardless, even if you don't like it, you still need to understand it because it is often asked. You can read more about how double-checked locking on Singleton works in this article.

49) How to create a thread-safe Singleton in Java?

This is the follow-up to the previous question. If you don't like double-checked locking and the interviewer asks for alternative methods to create a Singleton class, you can use JVM's class loading and static variable initialization features to create a Singleton instance, or use enum types to create a Singleton. I like this method very much. You can read this article for more information.

50) Write 3 The multithreading best practice you follow

This is a problem I like the most. I believe that when you write concurrent code to improve performance, you will also follow certain best practices. The following three best practices, I think, most Java programmers should follow:

Give your thread a meaningful name.

This makes it easier to find bugs or trace. Names like OrderProcessor, QuoteProcessor, or TradeProcessor are more meaningful than Thread-1. Thread-2 and Thread-3 Much better, give the thread a name related to the task it needs to complete. All major frameworks even JDK follow this best practice.

Avoid locking and narrow the scope of synchronization

Locking is costly, and context switching consumes more time and space. Try to use the minimum synchronization and locks, and narrow the critical section. Therefore, compared with synchronized methods, I prefer synchronized blocks, which give me absolute control over the lock.

Use more synchronous classes and less wait and notify

Firstly, CountDownLatch, Semaphore, CyclicBarrier, and Exchanger are synchronous classes that simplify coding operations, while it is difficult to control complex control flows with wait and notify. Secondly, these classes are written and maintained by the best enterprises, and they will continue to be optimized and improved in subsequent JDKs. By using these higher-level synchronization tools, your program can obtain optimization effortlessly.

Use concurrent collections instead of synchronized collections; this is another easy-to-follow and highly beneficial best practice. Concurrent collections have better scalability than synchronized collections, so using concurrent collections in concurrent programming is more effective. If you need to use a map next time, you should first think of using ConcurrentHashMap. My article Java Concurrent Collections has more detailed explanations.

51) How to force a thread to start?

This question is like how to force Java garbage collection, there is currently no sure method, although you can use System.gc() to perform garbage collection, but it does not guarantee success. There is no way to force a thread to start in Java, as it is controlled by the thread scheduler and Java does not publish related APIs.

52) What is the fork join framework in Java?

is part of the JDK7 is an efficient tool for Java developers to take full advantage of multi-processors on modern servers. It is specifically designed for those that can be recursively divided into many sub-modules, the purpose is to use all available processing power to improve program performance. One of the great advantages of the fork join framework is that it uses the work-stealing algorithm, which allows the working threads that can complete more tasks to steal tasks from other threads to execute. You can read this article for more information.

53What are the differences between calling wait() and sleep() methods in Java multithreading?

Both wait() and sleep() in Java programs cause some form of pause, and they can meet different needs. The wait() method is used for inter-thread communication, and if the waiting condition is true and other threads are awakened, it will release the lock. While the sleep() method only releases CPU resources or stops the execution of the current thread for a period of time, but does not release the lock. You can read this article for more information.

Declaration: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously, and this website does not own the copyright, has not been edited by humans, and does not bear relevant legal liabilities. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email for reporting, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)

You May Also Like