Reprint: http://blog.csdn.net/sunp823/article/details/49886051
The state of the lock: lock-free, biased, lightweight, and heavy-lock.
The bias lock applies to scenarios where only one thread accesses the synchronization block.
Lightweight locks, competing threads do not block, and are suitable for holding locks for a relatively short period of time. A thread that does not compete will spin to get the lock (the number of spins is not very certain, it needs to look at the hotspot source code to see, starting with Jni.cpp's Monitorenter function), to get the failure, the lightweight lock expands into a heavyweight lock, causing blocking.
First, the concept of spin lock
The first is a lock, similar to a mutex, and the basic function is for synchronization between threads (processes). Unlike a normal lock, a thread A will hang (block) if the thread B tries to acquire a lock after it acquires a normal lock, and if the two thread resource competition is not particularly intense, While the cost of switching the thread context caused by a processor blocking a thread is higher than the cost of waiting for the resource (the lock's holder keeps the lock time short), then thread B can not abandon the CPU time slice, but in "in situ" busy and so on, until the lock holder releases the lock, which is the principle of spin lock, A visible spin lock is a non-blocking lock.
Second, the spin lock may cause problems:
1. Excessive CPU time : If the current holder of the lock does not release the lock for a long time, the waiting person will occupy the CPU time slice for a long time, resulting in a waste of CPU resources, so can set a time, when the lock holder does not release the lock at this time, The waiting person will abandon the CPU time slice block;
2. Deadlock problem : Imagine that a thread has been trying to get a spin lock for two consecutive times (for example, in a recursive program), the first time this thread has acquired the lock, and when the second attempt to lock the lock has been detected (actually occupied by itself), then the thread will wait for itself to release the lock , and cannot continue execution, causing a deadlock. So recursive programs using spin locks should follow these guidelines: A recursive program must never invoke itself when holding a spin lock, or attempt to obtain the same spin lock when recursive calls are made.
Third, the implementation of a spin lock in Java:
Import java.util.concurrent.atomic.AtomicReference;
- Class SpinLock {
- Java Zhongyuan (CAS) operations
- Atomicreference<thread> owner = new Atomicreference<thread> (); Thread object holding spin lock
- private int count;
- Public void Lock () {
- Thread cur = thread.currentthread ();
- The lock function sets owner to the current thread and predicts that the original value is empty. The Unlock function sets owner to NULL, and the predicted value is the current thread. A loop is caused when a second thread calls the lock operation because the owner value is not null
- is executed until the first thread calls the Unlock function to set owner to NULL, and the second thread can enter the critical section.
- while (!owner.compareandset (null, cur)) {
- }
- }
- Public void UnLock () {
- Thread cur = thread.currentthread ();
- Owner.compareandset (cur, null);
- }
- }
- }
- Public class Test implements Runnable {
- static int sum;
- Private SpinLock lock;
- Public Test (SpinLock Lock) {
- This.lock = lock;
- }
- Public static void Main (string[] args) throws interruptedexception {
- SpinLock lock = new SpinLock ();
- for (int i = 0; i < ; i++) {
- Test test = new test (lock);
- Thread t = new thread (test);
- T.start ();
- }
- Thread.CurrentThread (). Sleep (1000);
- SYSTEM.OUT.PRINTLN (sum);
- }
- @Override
- Public void Run () {
- This.lock.lock ();
- sum++;
- This.lock.unLock ();
- }
- }
Spin lock principle and Java spin lock