Many core Java interview questions come from multi-threading and collections frameworks. Proficient practical experience is necessary when understanding the concept of core threads. This article collects some typical questions about Java threading, which are often asked by senior engineers.
0. What is multi-threaded synchronization in Java?
Under multi-threaded programs, synchronization can control access to shared resources. If there is no synchronization, when a Java thread is modifying a shared variable, another thread is using or updating the same variable, which can easily lead to incorrect results in the program.
1. Explain several ways to implement multi-threading?
A Java thread can implement the Runnable interface or inherit the Thread class to implement it. When you plan to inherit multiple times, you will prefer to implement Runnable.
2. What is the difference between Thread.start () and Thread.run ()?
The Thread.start () method (native) starts the thread and enters the ready state. When the CPU allocates time to the thread, the JVM schedules to execute the run () method.
3. Why do we need the run () and start () methods? Can we just use the run () method to complete the task?
We need the two methods of run () & start () because the JVM creates a separate thread different from the call of ordinary methods, so this work is done by the thread's start method. Start is implemented by the local method and needs to be called displayably. Another advantage of using these two methods is that any object can be run as a thread. As long as the Runnable interface is implemented, this avoids the multiple inheritance problems of Java caused by inheriting the Thread class.
4. What is the ThreadLocal class and how to use it?
ThreadLocal is a thread-level local variable, not a "local thread". ThreadLocal provides an independent copy of the variable for each thread that uses the variable. Each thread does not affect the copy of other thread objects when modifying the copy (Translator's Note).
Here are the key points of thread local variables:
A thread local variable (ThreadLocal variable) conveniently provides a separate variable for each thread.
ThreadLocal instances usually appear in a class as static private (private static) fields, which are used to associate a thread.
When multiple threads access ThreadLocal instances, each thread maintains an independent copy of the variables provided by ThreadLocal.
Commonly used uses can be seen in the DAO mode. When the DAO class is a singleton class, the database connection is independently maintained by each thread and does not affect each other. (Singleton based on thread)
5. When will the InvalidMonitorStateException be thrown and why?
When calling any of the methods in wait ()/notify ()/notifyAll (), if the current thread does not obtain the lock of the object, an exception of IllegalMonitorStateException will be thrown (that is, when the program does not execute any synchronization block or synchronization method of the object, it still tries to call wait ()/notify ()/notifyAll ()). Since the exception is a subclass of RuntimeExcpetion, the exception does not have to be caught (although you can catch it as long as you want). As a RuntimeException, such exceptions are not mentioned in the wait(), notify(), notifyAll() method signature.
6. What is the difference between Sleep (), suspend () and wait ()?
Thread.sleep () makes the current thread in a "Not Runnable" state at the specified time. The thread always holds the object's monitor. For example, if a thread is currently in a synchronization block or synchronization method, other threads cannot enter the block or method. If another thread calls the interrupt() method, it will wake up that "sleeping" thread.
Note: sleep() is a static method. This means that it is only valid for the current thread, and a common error is calling t.sleep(), (here t is a thread that is different from the current thread). Even if t.sleep() is executed, the current thread is going to sleep, not the t thread. t.suspend() is an outdated method. Using suspend() causes the thread to enter a stagnant state. The thread will always hold the object's monitor, and suspend() is likely to cause deadlock problems.
object.wait() makes the current thread come out of a "unrunable" state. Unlike sleep(), wait is an object method rather than thread. When calling object.wait (), the thread first needs to obtain the object lock of this object. The current thread must keep the lock object synchronized and add the current thread to the waiting queue. Then another thread can synchronize the same object lock to call object.notify (), which will wake up the thread that was originally waiting and then release the lock. Basically wait ()/notify () is similar to sleep ()/interrupt (), except that the former requires the object lock to be acquired.
7. What happens when using synchronization on static methods?
When synchronizing a static method, the "Class" object of the class will be obtained. Therefore, when a thread enters a synchronized static method, the thread monitor acquires the object lock of the class itself, and other threads cannot enter any static synchronization method of this class. It is not like an instance method, because multiple threads can access different instances simultaneously synchronous instance methods.
8. When a synchronization method has been executed, can the thread call the asynchronous instance method on the object?
Yes, an asynchronous method can always be called without any problems. In fact, Java does not do any checks for asynchronous methods, and lock objects are only checked in synchronization methods or synchronous code blocks. If a method is not declared as synchronous, even if you are using shared data, Java will still call it without checking whether it is safe, so be especially careful in this case. Whether a method is declared synchronous depends on critical section access. If the method does not access the critical section (shared resources or data structures), it is not necessary to declare synchronous.
Here is an example: Common class has two methods synchronizedMethod1() and method1(), and the MyThread class calls these two methods in an independent thread.
public class Common { public synchronized void synchronizedMethod1() { System.out.println("synchronizedMethod1 called"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("synchronizedMethod1 done"); } public void method1() { System.out.println("Method 1 called"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 1 done"); } } public class MyThread extends Thread { private int id = 0; private Common common; public MyThread(String name, int no, Common object) { super(name); common = object; id = no; } public void run() { System.out.println("Running Thread" + this.getName()); try { if (id == 0) { common.synchronizedMethod1(); } else { common.method1(); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Common c = new Common(); MyThread t1 = new MyThread("MyThread-1", 0, c); MyThread t2 = new MyThread("MyThread-2", 1, c); t1.start(); t2.start(); } }Here is the output of the program:
Running ThreadMyThread-1
synchronizedMethod1 called
Running ThreadMyThread-2
Method 1 called
synchronizedMethod1 done
Method 1 done
The results show that even if the synchronizedMethod1() method is executed, method1() will be called.
9. Can two threads call two different synchronous instance methods on an object?
No, because an object has synchronized the instance method, the thread acquires the object lock of the object. Therefore, other synchronization methods can only be executed after the method is released after the object lock is released. The following code example is very clear: the Common class has synchronizedMethod1() and synchronizedMethod2() methods, and MyThread calls these two methods.
public class Common { public synchronized void synchronizedMethod1() { System.out.println("synchronizedMethod1 called"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("synchronizedMethod1 done"); } public synchronized void synchronizedMethod2() { System.out.println("synchronizedMethod2 called"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("synchronizedMethod2 done"); } } public class MyThread extends Thread { private int id = 0; private Common common; public MyThread(String name, int no, Common object) { super(name); common = object; id = no; } public void run() { System.out.println("Running Thread" + this.getName()); try { if (id == 0) { common.synchronizedMethod1(); } else { common.synchronizedMethod2(); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Common c = new Common(); MyThread t1 = new MyThread("MyThread-1", 0, c); MyThread t2 = new MyThread("MyThread-2", 1, c); t1.start(); t2.start(); } }10. What is a deadlock
A deadlock means that two or more threads are infinitely blocked, and threads are waiting for each other for the required resources. This can happen when two threads try to acquire locks for other resources, and each thread is indefinitely waiting for the release of other resource locks unless a user process is terminated. As far as JavaAPI is concerned, thread deadlocks may occur in the following situation.
11. What is a thread starving to death and what is a live lock?
Although thread starvation and life locks are not considered common problems like deadlocks, they are like an encounter for designers of concurrent programming.
When all threads are blocked, or cannot be processed because the required resource is invalid, there are no non-blocking threads to make the resource available. Thread live locks in JavaAPI may occur in the following situations:
The questions here are not detailed, I hope they will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support to Wulin.com website!