The latest interview questions for the 2020 autumn recruitment: Concurrent programming high-frequency interview questions: reentrant lock + thread pool + memory model, etc. (including answers)

For a Java programmer, being able to master concurrent programming is one of the important criteria for judging his excellence. Because concurrent programming is the most obscure knowledge point in the Java language, it involves the basic abilities of operating system, memory, CPU, programming language, etc., and it tests a programmer's internal skills.
So how do you learn concurrent programming? There are many concurrent toolkits in the Java SDK. Do you have to memorize the advantages and disadvantages and usage scenarios of each tool? Of course not. If you want to learn concurrent programming, you need to learn from a single "Jumped out" from the knowledge and technology of China, looked at the problem from a high-level perspective, and gradually established its own knowledge system.

ReentrantLock and other explicit lock related issues

Question 1: Compared with Synchronized, what is the difference in the implementation principle of Reentrant Lock?

In fact, the realization principle of the lock is basically to achieve one goal: to make all threads see a certain mark. Synchronized achieves this goal by setting a mark in the object header. It is a JVM native lock implementation method. Reentrant Lock and all implementation classes based on the Lock interface are all implemented by using a volitile-modified int variable, and To ensure that each thread can have visibility and atomic modification of the int, its essence is based on the so-called AQS framework.

Question 2: So please talk about the AQS framework?

AQS (Abstract Queued Synchronizer class) is a framework used to build locks and synchronizers, the locks in various Lock packages (commonly used are Reentrant Lock, ReadWrite Lock), and others such as Semaphore, Count Down Latch, and even the early ones Future Task etc. are all based on AQS to build.

1. AQS defines a volatile int state variable internally, which represents the synchronization state: When the thread calls the lock method, if state=0, it means that no thread holds the lock of the shared resource, and the lock can be obtained and state=1; if state = 1, it means that a thread is currently using the shared variable, and other threads must join the synchronization queue to wait.

2. AQS completes the queuing work of threads acquiring locks through a synchronized queue with a doubly linked list structure formed by the internal classes of Node. When a thread fails to acquire the lock, it is added to the end of the queue.

  • The Node class is an encapsulation of the thread that wants to access the synchronization code. It contains the thread itself and its status called wait Status (there are five different values, which indicate whether they are blocked, whether they are waiting for wakeup, whether they have been cancelled, etc.). The Node node associates its prev node and next node to facilitate the thread to quickly wake up the next waiting thread after releasing the lock. It is a FIFO process.
  • The Node class has two constants, SHARED and EXCLUSIVE, which represent shared mode and exclusive mode respectively. The so-called shared mode is a lock that allows multiple threads to operate at the same time (the semaphore Semaphore is based on the shared mode of AQS), and the exclusive mode is that only one thread can operate on shared resources in the same time period, and redundant request threads need to be queued Wait (such as Reentran Lock).

3. AQS

Construct a waiting queue (there can be more than one) through the internal class Condition Object. When Condition calls the wait() method, the thread will join the waiting queue, and when the Condition calls the signal() method, the thread will move from the waiting queue to mobile synchronization Lock competition in the queue.

4. AQS

Each and Condition maintain different queues. When Lock and Condition are used, they actually move between the two queues.

Question 3: Please compare the similarities and differences between Synchronized and Reentrant Lock as much as possible.

Reentrant Lock is the implementation class of Lock, which is a mutually exclusive synchronization lock.

From a functional point of view, Reentrant Lock is more refined than Synchronized's synchronization operation (because it can be used like a normal object), and even implements advanced functions that Synchronized does not have, such as:

  • Waiting can be interrupted: When the thread holding the lock does not release the lock for a long time, the waiting thread can choose to give up waiting, which is useful for processing synchronized blocks with a very long execution time.
  • Attempt to acquire lock with timeout: acquire the lock within the specified time range, and return if the time is up and still cannot be acquired.
  • You can determine whether there are threads waiting in the queue to acquire the lock.
  • Can respond to interrupt requests: Unlike Synchronized, when the thread that acquired the lock is interrupted, it can respond to the interrupt, the interrupt exception will be thrown, and the lock will be released.
  • Fair lock can be achieved.

From the perspective of lock release, Synchronized is implemented at the JVM level. Not only can the synchronized lock be monitored through some monitoring tools, but also when the code execution is abnormal, the JVM will automatically release the lock; but using Lock does not work. Lock is implemented through code To ensure that the lock will be released, you must put un Lock() in finally{}.

From a performance perspective, the early implementation of Synchronized was relatively inefficient. Compared with Reentrant Lock, the performance of most scenarios is quite different. But it has been improved a lot in Java 6, when the competition is not fierce,

The performance of Synchronized is better than that of Reetrant Lock; under high competition, the performance of Synchronized will drop dozens of times, but the performance of Reetrant Lock can remain normal.

Question 4: How does Reentrant Lock achieve reentrancy?

Reentrant Lock internally customizes the synchronizer Sync (Sync implements both AQS and AOS, and AOS provides a way to hold a mutex lock). In fact, it uses the CAS algorithm to place the thread object when the lock is locked. In a doubly linked list, every time a lock is acquired, check whether the currently maintained thread ID is the same as the currently requested thread ID, and the same can be reentered.

Question 5: In addition to Reetrant Lock, which concurrency tools have you been exposed to in JUC?

Question 6: Please talk about Read Write Lock and Stamped Lock.

Question 7: How to synchronize Java threads with each other? Which synchronizers have you known? Please introduce them separately.

Question 8: Cyclic Barrier and Count Down Latch look very similar, please compare?

Java thread pool related issues

Question 1: How is the thread pool implemented in Java?

 In Java, the so-called "thread" in the thread pool is actually abstracted as a static internal class Worker, which is implemented based on AQS and stored in the Hash Set<Worker> workers member variable of the thread pool;

 The tasks that need to be executed are stored in the member variable work Queue (Blocking Queue<Runnable> work Queue). In this way, the basic idea of ​​the realization of the entire thread pool is: continuously take out the tasks that need to be executed from the work Queue and place them in the Workers for processing.

Question 2: How many core construction parameters are needed to create a thread pool?

The creation of thread pools in Java is actually very flexible. We can create thread pools with different behaviors by configuring different parameters. These parameters include: core Pool Size: the number of core threads in the thread pool.

  • maximum Pool Size: The maximum number of threads allowed in the thread pool.
  • Keep Alive Time: The survival time of idle threads when the number of core threads is exceeded.
  • work Queue: The queue that saves the task before the task is executed, and saves the Runnable task submitted by the execute method.

Question 3: How are the threads in the thread pool created? Was it created at the beginning with the start of the thread pool?

Obviously not. After the thread pool is initialized by default, the Worker is not started, and it is started only when there is a request. Whenever we call the execute() method to add a task, the thread pool will make the following judgments:

 If the number of running threads is less than the core Pool Size, then immediately create a thread to run this task;

 If the number of running threads is greater than or equal to core Pool Size, then put the task in the queue;

 If the queue is full at this time, and the number of running threads is less than the maximum Pool Size, then create a non-core thread to run the task immediately;

 If the queue is full and the number of running threads is greater than or equal to the maximum Pool Size, the thread pool will throw an exception Reject Execution Exception. When a thread completes its task, it will remove the next task from the queue for execution. When a thread has nothing to do for a certain period of time (Keep Alive Time), the thread pool will be disconnected.

If the number of currently running threads is greater than the core Pool Size, then this thread is stopped. So after all tasks of the thread pool are completed, it will eventually shrink to the size of the core Pool Size.

Question 4: Since it is mentioned that different thread pools can be created by configuring different parameters, what thread pools are implemented by default in Java? Please compare their similarities and differences.

Question 5: How to submit threads in the Java thread pool?

…………………………

Java memory model related issues

Question 1: What is Java's memory model, and how do threads in Java see each other's variables?

Java's memory model defines the access rules of each variable in the program, that is, the low-level details such as storing variables in the virtual machine and removing them from the memory.

The variables here include instance fields, static fields, and elements that make up the array object, but do not include local variables and method parameters. Because these are thread-private and will not be shared, there is no competition problem.

How do threads in Java see each other's variables? The concepts of main memory and working memory are defined in Java:

All variables are stored in the main memory, and each thread has its own working memory, which stores a copy of the main memory copy of the variables used by the thread. All operations (reading, assignment) of variables by threads must be performed in working memory, and variables in main memory cannot be directly read and written. Different threads cannot directly access the variables of each other's working memory, and the transfer of variable values ​​between threads needs to pass through the main memory.

Question 2: Please talk about the characteristics of volatile and why it can guarantee the visibility of variables to all threads?

Question 3: Since volatile can guarantee the visibility of variables between threads, does it mean that operations based on volatile variables are concurrently safe?

Question 4: Please compare the similarities and differences between volatile and Synchronized.

Question 5: Please talk about how Thread Local solves concurrency safety?

Question 6: Many people say that Thread Local should be used with caution. Tell us about your understanding, what should I pay attention to when using Thread Local?

……………………

Synchronized related issues

Question 1: Have you ever used Synchronized? What is its principle?

Question 2: You just mentioned acquiring a lock on an object. What exactly is this "lock"? How to determine the lock of an object?

Question 3: What is reentrancy, and why is Synchronized a reentrant lock? Reentrancy

Question 4: What optimizations does JVM make to Java's native locks?

Question 5: Why is Synchronized an unfair lock?

Question 6: What is lock elimination and lock coarsening?

Question 7: Why is Synchronized a pessimistic lock? What is the principle of optimistic locking? What is CAS and what are its characteristics?

Question 8: Is optimistic locking necessarily good?

other problems

JAVA Concurrent Knowledge Base

JAVA thread implementation / creation method

4 thread pools

Thread life cycle (state)

4 ways to terminate threads

The difference between sleep and wait

The difference between start and run

JAVA background thread

JAVA lock

Basic thread method

Thread context switch

Synchronization and deadlock

Principle of Thread Pool

JAVA blocking queue principle

Usage of CyclicBarrier, CountDownLatch, Semaphore

The role of the volatile keyword (variable visibility, prohibit reordering)

How to share data between two threads

ThreadLocal function (thread local storage)

The difference between synchronized and ReentrantLock

ConcurrentHashMap concurrency

Thread scheduling used in Java

Process scheduling algorithm

What is CAS (compare and exchange-optimistic locking mechanism-lock spin)

What is AQS (Abstract Queue Synchronizer)

All the concurrent programming interview questions have been combined into documents. Due to the length of the space, there is no way to upload all of them. Partners who need a complete compressed document can "add my VX assistant to get it for free"

                                                            

Information display

 

Concurrent programming high-frequency interview questions: reentrant lock + thread pool + memory model, etc. (including answers)

 

Concurrent programming high-frequency interview questions: reentrant lock + thread pool + memory model, etc. (including answers)

 

Knowledge brain map:

Concurrent programming high-frequency interview questions: reentrant lock + thread pool + memory model, etc. (including answers)

 

Can't help but want to complain, knowledge points are many and complicated. . . . . . . . .

Concurrent programming high-frequency interview questions: reentrant lock + thread pool + memory model, etc. (including answers)

Guess you like

Origin blog.csdn.net/a159357445566/article/details/108708515