This article brings you relevant knowledge about java, which mainly organizes issues related to thread interview questions, including the difference between sychronied modified ordinary methods and static methods, CAS lock-free programming The principles, the difference between volatile and synchronize, etc., let’s take a look at them together, I hope it will be helpful to everyone.
Recommended study: "java video tutorial"
Object locks are used for object instance methods, or an object instance, and class locks are used for static methods of a class or class objects of a class. We know that there can be many object instances of a class, but each class has only one class object, so the object locks of different object instances do not interfere with each other, but there is only one class lock for each class.
One thing that must be noted is that in fact, class lock is only a conceptual thing and does not actually exist. Class lock actually locks the corresponding class object of each class. Class locks and object locks also do not interfere with each other.
Visibility means that when multiple threads access the same variable, if one thread modifies the value of the variable, other threads can immediately see the modified value.
Since all operations on variables by threads must be performed in the working memory and cannot directly read and write variables in the main memory, then for the shared variables V, they are first in their own working memory and then synchronized to the main memory. . However, it will not be flushed to the main memory in time, but there will be a certain time difference. Obviously, at this time, thread A's operation on variable V is no longer visible to thread B.
To solve the problem of shared object visibility, we can use the volatile keyword or lock.
Current processors basically support the CAS() instruction, but the algorithms implemented by each manufacturer are different. Each CAS operation process contains three operators: a memory address V, An expected value A and a new value B. During operation, if the value stored at this address is equal to the expected value A, then the value at the address is assigned to the new value B, otherwise no operation is performed.
The basic idea of CAS is that if the value at this address is equal to the expected value, give it a new value. Otherwise, do nothing but return the original value. Loop CAS is to continuously perform cas operations in a loop until it succeeds. We can also talk about three major problems with CAS.
A thread can repeatedly enter any code block that is synchronized with a lock it already owns. Synchronized and ReentrantLock are both reentrant locks. In terms of implementation, every time a thread acquires a lock, it determines if the thread acquiring the lock is itself, and simply accumulates the counter. Each time the lock is released, the counter is decremented until the calculator returns to zero, indicating that the thread has been completely released. Lock. The bottom layer is implemented using AQS in JUC.
It is the basic framework used to build locks or other synchronization components. For example, ReentrantLock, ReentrantReadWriteLock and CountDownLatch are implemented based on AQS. It uses an int member variable to represent the synchronization status, and completes the queuing work of resource acquisition threads through the built-in FIFO queue. It is a variant implementation of the CLH queue lock. It can achieve 2 synchronization methods: exclusive and shared.
The main way of using AQS is inheritance. Subclasses inherit AQS and implement its abstract methods to manage synchronization status. The design of the synchronizer is based on the template method pattern, so if we want to implement our own synchronization tool class, we need to cover it. Several overridable methods, such as tryAcquire, tryReleaseShared, etc.
The purpose of this design is that synchronization components (such as locks) are user-oriented. It defines the interface for users to interact with synchronization components (for example, it can allow two threads to access in parallel), hiding implementation details; the synchronizer is user-oriented. is the implementer of locks. It simplifies the implementation of locks and shields underlying operations such as synchronization state management, thread queuing, waiting and waking up. This effectively isolates the areas that users and implementers need to focus on.
Internally, AQS maintains a shared resource state and uses the built-in FIFO to complete the queuing work of resource acquisition threads. The queue is composed of Node nodes one by one. Each Node node maintains a prev reference and next reference, which point to its own predecessor and successor nodes respectively, forming a two-ended doubly linked list.
Synchronized (this) principle: involves two instructions: monitorenter, monitorexit; let’s talk about the synchronization method. Judging from the decompilation results of the synchronization method, the synchronization of the method is not achieved through the instructions monitorenter and monitorexit. Compared with Ordinary methods have an additional ACC_SYNCHRONIZED identifier in the constant pool.
The JVM implements method synchronization based on this identifier: when the method is called, the calling instruction will check whether the ACC_SYNCHRONIZED access flag of the method is set. If it is set, the execution thread will first obtain the monitor. After the acquisition is successful, The method body can be executed, and the monitor can be released after the method is executed. During method execution, no other thread can obtain the same monitor object again.
Introduction of technologies such as spin lock, adaptive spin lock, lock elimination, lock coarsening, biased lock, lightweight lock, escape analysis and other technologies to reduce the cost of lock operations.
Object locks are used for object instance methods or an object instance. Class locks are used for static methods of a class or class objects of a class. We know that there can be many object instances of a class, but each class has only one class object, so the object locks of different object instances do not interfere with each other, but there is only one class lock for each class.
One thing that must be noted is that in fact, class lock is only a conceptual thing and does not actually exist. Class lock actually locks the corresponding class object of each class. Class locks and object locks also do not interfere with each other.
There is no guarantee that the role of DCL is: volatile will ensure the visibility and ordering of modified variables, ensuring that in singleton mode, the execution order when creating an object must be
Volatile is the lightest synchronization mechanism. Volatile guarantees the visibility when different threads operate on this variable, that is, if one thread modifies the value of a variable, the new value is immediately visible to other threads. However, volatile cannot guarantee the atomicity of operations, so composite write operations under multi-threads will cause thread safety issues.
The keyword synchronized can be used to modify methods or in the form of synchronized blocks. It mainly ensures that multiple threads can only have one thread in a method or synchronized block at the same time. It ensures that threads access variables safely. Visibility and exclusivity, also known as built-in locking mechanisms.
The Daemon thread is a support thread because it is mainly used for background scheduling and support work in the program. This means that when there are no non-Daemon threads in a Java virtual machine, the Java virtual machine will exit. A thread can be set as a Daemon thread by calling Thread.setDaemon(true). We generally don't use it. For example, the garbage collection thread is the Daemon thread.
Thread abort: Either the run execution is completed, or an unhandled exception is thrown, causing the thread to end early. The APIs corresponding to the thread Thread for suspending, resuming, and stopping operations are suspend(), resume(), and stop(). However, these APIs are out of date and are not recommended for use. Because it will cause the program to work in an uncertain state.
Safe suspension is when other threads interrupt a certain thread A by calling its interrupt() method. The interrupted thread determines whether it has been interrupted through the thread method isInterrupted(), or it can be called The static method Thread.interrupted() is used to determine whether the current thread is interrupted, but Thread.interrupted() will also rewrite the interrupt flag bit to false.
The yield() method: causes the current thread to give up CPU ownership, but the time for giving up cannot be set. The lock resource will not be released. All threads executing yield() may be selected again by the operating system and executed immediately after entering the ready state.
After yield() and sleep() are called, the lock held by the current thread will not be released.
After calling the wait() method, the lock held by the current thread will be released, and after the current thread is awakened, it will compete for the lock again. The code behind the wait method will be executed only after the lock is competed.
Wait is usually used for interaction between threads, sleep is usually used to pause execution, and the yield() method causes the current thread to give up CPU ownership.
The wait thread uses notify/notifyAll() to wake up.
sleep itself supports interrupts. If the thread is interrupted during sleep, an interrupt exception will be thrown.
The status of threads in Java is divided into 6 types:
ThreadLocal is a special variable in Java. ThreadLocal provides a copy of the variable for each thread, so that each thread does not access the same object at a certain time, thus isolating the data sharing of data by multiple threads.
In terms of internal implementation, each thread has a ThreadLocalMap inside, which is used to save a copy of the variables owned by each thread.
During the development process, rational use of thread pools can bring 3 benefits.
First: Reduce resource consumption.
Second: Improve response speed.
Third: Improve the manageability of threads.
It can be implemented using the join method.
Recommended study: "java video tutorial"
The above is the detailed content of Summarize and organize Java thread interview questions. For more information, please follow other related articles on the PHP Chinese website!