Pessimistic lock and optimistic lock and lock status

Pessimistic locks:
always assume the worst case, get a time when data modification think others will, so every time she took the data will be locked, so people want to take this data will be blocked until the lock to get it . Traditional relational database inside to use a lot of this locking mechanism, such as row locks, table locks, read locks, write locks, are locked before doing the first operation, the sync Java inside: synchronized keyword is realized pessimistic locking.
Each execution of the critical section of code can create conflicts, so the current thread to acquire the lock of
candidates will also block other threads to acquire the lock
pessimistic locking mechanism has the following problems:

  1. In multi-threaded competition, lock, release the lock will lead to more context switching and scheduling delays, causing performance problems.
  2. A thread holding the lock will cause all other required this lock thread is suspended.
  3. If a high priority thread to wait for a lower priority thread releases the lock would lead to priority inversion, causing performance risk.

Optimistic locking:
every time that others pick up data are not modified, so it will not be locked, but when the update will determine what others during this time did not go to update the data, you can use the mechanisms of the version number. Optimistic locking is suitable for the types of applications to read, like similar write_condition mechanisms provided by the database, in fact, optimistic locking is provided. Java.util.concurrent.atomic package in Java following atomic variable classes is the use of one implementation of the optimistic locking CAS achieved.
NOTE: Each unlocked but assuming no concurrency conflicts away to complete an action, if it fails because of a concurrency violation retry until it succeeds
CAS operations: (the Compare and swap)
CAS process is relatively exchange: CAS (V, O, N), three values are: an actual value V stored in the memory address; new updated value of N; O expected value (old value).
(1) when V and O are the same, that is to say the actual value of the old value and the same memory indicates that the value has not been changed by other threads, that is, the old value O is for now the latest value, and naturally can be a new The value of N is assigned to V.
(2) V and O are not the same, indicating that the value has been another thread to turn over the old value of O is not the latest version of the value, so you can not assign a new value V N, V can be returned.
When multiple threads using a CAS operating variables, only one thread will be successful, and successful update, the rest will fail. Failure of thread to retry (retry), of course, can choose to suspend thread.
CAS implementation requires hardware support instruction set
can only be used CMPXCHG instructions provided by the processor implemented in the JDK1.5 virtual machine.
Here Insert Picture Description
When synchronization is to get the object's monitor, that is, to obtain the object lock
lock object:
similar to a sign of the object, then this flag is stored in the object header Java objects.
There are four kinds of lock state.
Level from low to high are: lock-free status, tend to lock status, lock status lightweight, heavyweight lock state of
these states will be gradually upgraded with competition. And only the upgrade can not be downgraded.
Here Insert Picture Description
1. biased locking: four states are the most optimistic in a lock from start to finish only one thread requests a lock.
Biased locking obtain: When a thread to acquire the lock and access the sync block, will lock the recording head and the object in the stack frame store lock bias thread ID, since the thread need not be operated when CAS sync blocks entry and exit to lock and unlock, simply test the head of Mark Word objects in memory if the current thread pointing to bias lock. If the test is successful, it indicates that the thread has acquired the lock. If the test fails, you will need to re-test Mark Word in biased locking identity is set to 1 (indicating the current is biased lock): If not set, the CAS compete lock; if set, try using CAS object head biased locking points to the current thread.
2. Lightweight locks:
a plurality of threads at different requests for the same period of time lock
locking:
the thread before performing sync blocks, the JVM stack frame may be created in the current thread lock space for storing records, and Object head Mark Word copied to lock the record, officially known as DisplacedMark
Word. The thread then attempt to use the object header to CAS Mark Word replacement recording pointer to point to the lock. If successful, the current thread to acquire the lock, and if that fails, represents another thread lock contention, the current thread will try to use to get the spin lock.
3. heavyweight lock:
multiple threads at the same time access the same lock.

Lock coarsening:
the locking together of multiple unlocking operations into one, a plurality of consecutive extended lock to become a greater range lock
code for:

public class LockCu {
//原始
//   private  static  StringBuffer sb=new StringBuffer();
//
//    public static void main(String[] args) {
//        sb.append("a");
//        sb.append("b");
//        sb.append("c");
//        //共加锁解锁了6次
//    }

//粗化
private final static StringBuilder sb=new StringBuilder();//fianl,防止局部变量被修改  StringBuilder线程安全

    public static void main(String[] args) {
        synchronized (sb){         //锁粗化
            sb.append("a");
        sb.append("b");
        sb.append("c");
            System.out.println(sb.toString());
        }
    }
}

Deadlock:
a thread to wait another thread completes execution can continue after completion. Related thread waits for each other will result in a deadlock.
Example: code for:

public class TestDeadLock {
    public static void main(String[] args) {
        final  Book book=new Book();
        final  Pen pen=new Pen();
       Thread threadA=new ThreadA(pen,book);
       threadA.setName("A");
       Thread threadB=new ThreadB(pen,book);
       threadB.setName("B");
        threadA.start();
        threadB.start();

    }
}
class Pen{
    private String name="笔";

    public String getName() {
        return name;
    }
}
class Book{
private String name="本";

    public String getName() {
        return name;
    }
}
class ThreadA extends Thread {
private final Pen pen;
private final Book book;
ThreadA(Pen pen,Book book){
    this.pen=pen;
    this.book=book;
}
    public void run() {
    synchronized (this.pen){
        System.out.println(Thread.currentThread().getName()+"有笔,缺个本");
        synchronized (this.book){
            System.out.println(Thread.currentThread().getName() + " 有笔,有本");
        }
    }

        }

    }
    class ThreadB extends Thread {
        private final Pen pen;
        private final Book book;

        ThreadB(Pen pen, Book book) {
            this.pen = pen;
            this.book = book;
        }

        public void run() {
            synchronized (this.book) {
                System.out.println(Thread.currentThread().getName() + "有本,缺个笔");
                synchronized (this.pen) {
                    System.out.println(Thread.currentThread().getName() + " 有笔,有本");
                }

            }
        }
    }

The result:
Here Insert Picture Description
In order to prevent deadlocks, you can add a time sleep (), and the majority will not deadlock.
Excessive synchronization will cause a deadlock for locking resources must be careful not to "ring"

Guess you like

Origin blog.csdn.net/weixin_42373873/article/details/91358538
Recommended