Interview questions: Ten questions that Java multithreading must master

1. Process and thread? Parallelism and Concurrency?
A process represents a running program and is the basic unit of resource allocation and scheduling. Processes have three characteristics:
1. Independence: independent resources, private address space, and processes do not affect each other.
2. Dynamic: The process has a life cycle.
3. Concurrency: Multiple processes can run concurrently on a single-core CPU.
A thread represents a sequential execution flow in a process, and multithreading is multiple sequential execution flows in a process. A thread, also known as a lightweight process, is the basic unit of system operation.
Advantages of multithreading (process thread difference):
1. Memory cannot be shared between processes, it is easier to share memory between threads, and multiple threads can cooperate to complete process work;
2. The cost of creating a process for resource allocation is much higher than creating a thread, so multithreading is more efficient in a high-concurrency environment.

 
Parallelism and Concurrency:
Parallelism means that when multiple cores, multiple CPUs or multiple machines process the same piece of processing logic, multiple execution streams are executed together at the same time.
Concurrency means: through the scheduling algorithm of the CPU, the user feels like processing multiple tasks at the same time, but only one execution flow occupies the CPU execution at the same time. Even multi-core and multi-CPU environments use concurrency to improve processing efficiency.
There are two main CPU scheduling algorithms:
1. Time-sharing scheduling: each thread obtains the right to use the CPU in turn, and each thread has an average CPU time slice.
2. Preemptive scheduling: This scheduling model is used by the Java virtual machine. In this scheduling method, the thread with the highest priority will be scheduled first according to the thread priority. If the thread priority is the same, the thread will be randomly selected for execution.

 
2. What is PCB?
The process control block is the most important data structure of the process, which records the identification of the process, scheduling information, control information, and the state of the processor. The PCB will be created when the process is created, and will die when the process dies, with the entire life cycle of the PCB.
Here are a few things to know:
1. The process identifier is used to uniquely identify a process. A process usually has two kinds of identifiers: internal identifiers and external identifiers.
2. The processor state information is mainly composed of the contents of various registers of the processor. While the processor is running, a lot of information is placed in registers. When the processor is interrupted, all this information is saved in the PCB so that when the process is re-executed, execution can be resumed from the point where it was interrupted.
3. Process scheduling information includes process status, process priority, other information required for process scheduling, and events (blocking reasons).
4. Process control information includes addresses of programs and data, process synchronization and communication mechanisms, resource lists, and link pointers.
5. The organization mode of the process control block is the link mode and the index mode.

 
3. Four ways to create threads in Java?
1. Inherit the Thread class and implement the run() method.
2. Implement the Runnable interface and implement the run() method. The Runnable instance object is passed in as the target parameter in the Thread constructor, acting as the thread execution body. This method is suitable for situations where multiple threads share resources.
3. Implement the Callable<Class> interface and implement the call() method.
 
There are two main differences between the call() method and the run() method:
1. The call() method can have a return value, and the return value type needs to be the same as the generic type when the interface is declared.
2. The call() method can throw an exception.
Using this method, the steps are more complicated than the first two methods:
1. When declaring the interface, you need to specify the generic type, and the return value type of the call() method must be consistent with the generic type.
2. Use FutureTask<Class> to encapsulate the Callable instance object and pass it in as the target parameter in the Thread constructor.
3. After calling start(), you can use the get() method of FutureTask to get the return value.
4. Implement the java.util.concurrent.ThreadFactory interface, implement the newThread(Runnable r) method, and customize the creation details.

 
4. Four ways for Java to terminate a thread? (See blog http://blog.csdn.net/zhangliangzi/article/details/52484302 )
1. Natural termination. After the execution of the run() method ends, the thread automatically terminates .
2. Use the stop() method, which has been deprecated.
3. Use the volatile flag (in fact, the natural death of external control).
4. Use the interrupt() method to interrupt running and blocking threads. (About interrupt(), when the interrupt() method is called, the interrupt state is changed immediately, but if it is not in the blocking state, an exception will not be thrown; if the interrupt state is interrupted after entering the blocking state, it will be thrown immediately An exception occurs. However, the process of acquiring the synchronized lock cannot be interrupted. For details, please refer to: http://blog.csdn.net/zhangliangzi/article/details/52485319
Note: When a thread throws an uncaught exception or error, the thread terminates abnormally.

 
5. What is the difference between the sleep() method and the wait() method? Why does the wait() method belong to the Object class?
All of them make the thread "wait" for some time, but:
The sleep() method is a method under the Thread class, which controls the sleep of the thread. The lock will not be released during the sleep process. After the sleep() time expires, it enters the ready state and waits for scheduling .
The wait() method is a method under the Object class. It controls the thread to wait. The waiting process will release the lock . After being notified (), it will enter the ready state and wait for scheduling.
 
As for why the wait() method belongs to the Object class instead of the Thread class, it is because:
The wait() method is used when multiple threads contend for a lock (usually an object locked by Synchronized). Only one thread can acquire the lock at the same time, and other threads must wait in the thread queue. The action object is the locked object, so the maintenance of the thread queue should be handed over to the Object. If it is given to Thread, then each Thread must know the status of other Threads, which is not reasonable.

 
6. What is the difference between the start() method and the run() method?
The start() method is used to start the thread, it will change the thread state from the new state to the ready state, and allocate the thread's private method stack, program counter and other resources to the thread, and the start() method will automatically execute the run() method as a thread body.
The run() method itself is no different from the ordinary method, and calling the run() method directly will not have the meaning of a thread.

 
7. Briefly describe the life cycle of threads
1. Create a new state. The Thread object with the thread execution body is created through the above methods, and the new state is entered.
2. In the ready state, calling the start() method of the Thread object will allocate the thread's private method stack and program counter resources to the thread. If the CPU resource is obtained, the thread will change from the ready state to the running state. In other words, the thread in the ready state has all the necessary resources except the CPU.
3. In the running state, the thread in the ready state will turn into the running state when it gets CPU resources, and execute the run() method. Of course, when the yield() thread is called to yield, the thread will change from the running state to the ready state, but this process may be extremely short-lived. If the current thread has a higher priority, even after yielding, it will directly to run state.
4. Blocking state, the methods that will lead to blocking state mainly include: sleep() method, wait() method, join() method, waiting for lock acquisition, waiting for IO and so on. After these situations are processed, it will turn to the ready state, waiting for scheduling.
5. Termination state, including several situations mentioned in the fourth question.

 
8. What is the background thread? What are the applications?   Daemon thread
A background thread, as its name suggests, is a thread that works in the background, and its task is to provide services for other threads, also known as "daemon threads" and "elf threads". Set the thread as a background thread by calling the setDeamon(true) method before the start() method call . Background threads will be notified of death by the JVM after the foreground thread dies.
The largest application of background threads is the garbage collection thread, which is a typical background thread.

 
9. What are the common lock types in Java? Please briefly describe its characteristics.
1. Synchronized object synchronization lock: synchronized is a lock on an object, which can act on objects, methods (equivalent to locking this object), static methods (equivalent to locking Class instance objects, and all locked objects of the class) ) to ensure thread safety in concurrent environments. Only one thread can acquire the lock at a time.
The underlying implementation is through the use of the object monitor Monitor, each object has a monitor, when the thread tries to acquire the Synchronized locked object, it will request the object monitor (Monitor.Enter() method), if the monitor is idle , the request is successful and the right to execute the locking code will be obtained; if the monitor is already held by another thread, the thread enters the synchronization queue and waits.
2. Lock synchronization lock: Similar to the synchronized function, it can be analyzed from the difference between Lock and synchronized:
1. Lock can acquire locks non-blockingly through the tryLock() method. Returns true immediately if the lock is acquired, otherwise returns false immediately. This method also has an overloaded method tryLock(long time, TimeUnit unit) with timing waiting. During the timing period, if the lock is acquired, it returns true immediately, otherwise it returns false after the timing ends. Can be interrupted during the timed wait, throwing InterruptException. Synchronized cannot be interrupted in the process of acquiring the lock.
2. Lock can acquire locks through the lockInterrupt() method, which is different from the lock() method in that it can respond to interruptions and throw InterruptException exceptions when waiting.
3. Synchronized is an implicit lock and unlock, and Lock must display the lock and unlock, and the unlock should be placed in findly to ensure that it will be unlocked, and Synchronized will automatically unlock when an exception occurs. But also because of this, Lock is more flexible .
4. Synchronized is a design at the JVM level, which locks objects and is based on object monitors. Lock is implemented in code.
3. Reentrant locks: ReentrantLock and Synchronized are both reentrant locks. Reentrant means that the thread that acquired the lock can recursively acquire the lock again. After all locks are released, other threads can acquire locks.
4. Fair lock and unfair lock: "Fairness" refers to whether the thread that waits the longest will obtain the resource. It is fair if the order in which locks are acquired is sequential. Unfair locks are generally more efficient than fair locks. ReentrantLock can control the fairness of the lock through the constructor parameter.
5. ReentrantReadWriteLock read-write lock: It is a non-exclusive lock. General locks are exclusive locks, that is, only one thread can access at the same time, such as Synchronized and Lock. The read-write lock means that multiple threads can acquire the read-lock and read resources at the same time. When there is a write operation, the write-lock is acquired, and the read-write operation after the write operation will be blocked until the write-lock is released. Read-write locks are suitable for scenarios with many write operations and are more efficient.
6. Optimistic locks and pessimistic locks: There are not many practical application classes in Java, and most of them are used in database locks. See: http://blog.csdn.net/sdyy321/article/details/6183412
7. Deadlock: A deadlock occurs when two threads wait for each other to acquire each other's object monitors. In the event of a deadlock, the entire program will neither have exceptions nor prompts, but all threads will be blocked. Deadlocks typically occur with multiple simultaneous monitors.

 
10. What is volatile and automicInteger? how to use?
There are three factors that need to be carefully considered in a concurrent environment, atomicity, visibility, and orderliness.
Volatile is mainly used to solve visibility. It modifies variables, which is equivalent to adding a "memory fence" before and after the current statement. The code before the current code will not be rearranged after the current code, and the instructions after the current code will not be rearranged before the current code, which ensures order to a certain extent. The main function of volatile is to invalidate the cache in all threads when modifying the value of the volatile-modified variable, and force writing to the common main memory, ensuring the consistency of each thread. It can be seen as a lightweight Synchronized. For details, please refer to: http://www.cnblogs.com/dolphin0520/p/3920373.html .
automicXXX is mainly used to solve atomicity, there is a very classic problem: is i++ an atomic opcode? The answer is no, it is actually a two-step operation, one is to take the value of i, and the other is ++. After taking the value, if another thread modifies the value, the i value of the current thread is the old data, which will affect the final operation result. Using automicXXX allows non-blocking and atomic addition and subtraction operations to data. For details, please visit: http://ifeve.com/java-atomic/
 
Note: What is listed here is only the most basic knowledge of Java multi-threading, and it is also the most frequently asked questions by interviewers. First lay a solid foundation, and then discuss the underlying principles or advanced usage. In addition to these ten questions, here are some other recommendations. data of:
How does the bottom layer of the JVM implement synchronization: http://www.open-open.com/lib/view/open1352431526366.html
Detailed explanation of Java thread pool: http://blog.csdn.net/zhangliangzi/article/details/52389766
In-depth analysis of Java thread pool: http://www.cnblogs.com/dolphin0520/p/3932921.html
Principle analysis of ConcurrentHashMap: http://www.cnblogs.com/ITtangtang/p/3948786.html
Detailed explanation of Java blocking queue: http://ifeve.com/java-blocking-queue/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325358203&siteId=291194637