On the Concurrency

Lock thread concurrency -synchronized and simple cognitive

A few days ago just learned more about the thread, some questions during the encounter when validating a variety of methods and multi-threading, in the case of high concurrency, and how the program can be done to ensure the normal operation in accordance with our expectations down, which is what we the next inquiry under concurrency of some common thread-safe method, etc., only personal opinion, forget the majority of alumni correct.

synchronized genlock

  1. characteristic

    1.1 classes, methods and the use of synchronized code blocks may ensure proper mutex thread concurrency, synchronization codes ( atomicity );

    1.2 ensure the visibility of shared resources ( similar volaite ), each thread has its own buffer area, if locked resource has changed, each thread will abandon get away from the thread cache system main memory to re-obtain the latest the ( visibility )

    1.3 In the case of concurrent, can guarantee an orderly execution threads ( ordered )

  2. principle

    Synchronization lock can be locked on the class, and the code block objects, each object is modified, will monitor the monitor operates through a thread calls acquired;

    When a thread calls the object, when the number of threads 0 if the object's monitor to enter, the owner is the current thread to lock an object, the value of +1, while the other thread calls will be blocked waiting;

    If the current thread acquired object again, and then monitors the value +1 into the thread;

    After the completion of the release of resources in the thread execution, the number of threads to enter the monitor is 0, the blocked thread sequential acquisition target.

    When we lock object or class (code blocks):

    public class Test1 {
    
     private static Boolean flag = true;
    
     public void add() {
         synchronized(flag) {
             if (flag) {
                 flag = false;
             }
         }
     }
    
     public static void main(String args[]) {
         Test1 t1 = new Test1();
         t1.add();
         System.out.println(flag);
     }
    }
    // 查看编译字节文件
    public Test1();
      descriptor: ()V
      flags: ACC_PUBLIC
      Code:
        stack=1, locals=1, args_size=1
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
        LineNumberTable:
          line 1: 0
    
    public void add();
      descriptor: ()V
      flags: ACC_PUBLIC
      Code:
        stack=2, locals=3, args_size=1
           0: getstatic     #2                  // Field flag:Ljava/lang/Boolean;
           3: dup
           4: astore_1
           5: monitorenter
           6: getstatic     #2                  // Field flag:Ljava/lang/Boolean;
           9: invokevirtual #3                  // Method java/lang/Boolean.booleanValue:()Z
          12: ifeq          22
          15: iconst_0
          16: invokestatic  #4                  // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
          19: putstatic     #2                  // Field flag:Ljava/lang/Boolean;
          22: aload_1
          23: monitorexit
          24: goto          32
          27: astore_2
          28: aload_1
          29: monitorexit
          30: aload_2
          31: athrow
          32: return
        Exception table:
           from    to  target type
               6    24    27   any
              27    30    27   any
    
    

    Bytecode by looking (using javap -v / verbose command to view the encoded file), it seems, by the JVM monitorenter and monitorexit monitors entry and exit, in order to ensure release the object lock, the presence of multiple monitorexit;

    When we lock in the method body:

    public class Test {
    
     private int num;
    
     public synchronized int add() {
         return num ++;
     }
    
     public static void main(String[] args) {
         Test t = new Test();
         System.out.println(t.add());
     }
    }
    // 字节码
    public Test();
      descriptor: ()V
      flags: ACC_PUBLIC
      Code:
        stack=1, locals=1, args_size=1
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
        LineNumberTable:
          line 1: 0
    
    public synchronized int add();
      descriptor: ()I
      flags: ACC_PUBLIC, ACC_SYNCHRONIZED
      Code:
        stack=4, locals=1, args_size=1
           0: aload_0
           1: dup
           2: getfield      #2                  // Field num:I
           5: dup_x1
           6: iconst_1
           7: iadd
           8: putfield      #2                  // Field num:I
          11: ireturn
        LineNumberTable:
          line 6: 0
    

    It appeared ACC_SYNCHRONIZED variable, and the locking block is different, according to the method body lock ACC_SYNCHRONIZED to true / identification to determine whether to false synchronization, the synchronization lock block is performed by synchronizing monitorenter and monitorexit instructions

  3. Scenarios

    In multiple threads, we can be achieved by locking To achieve resource sharing; synchronized block is not recommended logic is too complex

Lock

  1. characteristic

    • Lock need to manually lock, manual unlocking (lock (); unlock ();)

    • tryLock nonblocking mode to acquire the lock, it is determined whether the lock is already occupied, it returns false, true lock is occupied; can also set the time, attempting to acquire the lock within a time;

      lock.tryLock(6000, TimeUnit.MILLISECONDS) // 线程AB先后获取锁,A占有锁B会在后面的6秒尝试再次获取获取不到直接进入false逻辑。
    • lock.lockInterruptibly (), waiting to acquire the lock thread can interrupt thread.interrupt (); statement throws an exception InterruptedException

    • Lock release latch to release the lock if an exception to be captured in finally in

  2. principle

    Lock lock unlock common method of implementation class ReentrantLock, ReadWriteLock the like, which basically relies AQS (AbstractQueuedSynchronizer) provided.

to sum up

  1. The difference between synchronized and lock
    • synchronized jvm will automatically release the lock after executing the monitorexit command, lock need to manually release the lock, or likely to cause thread deadlock
    • Lock is an interface, synchronized keyword
    • Lock can determine whether the thread has a lock, you can set the time to acquire a lock
    • Lock locks suitable for mass synchronization synchronization code, synchronized lock for a small amount of code synchronization issues.
  2. To use synchronized, there must be two or more threads. Single-threaded use does not make sense, but also to reduce the efficiency.
  3. To use synchronized, thread synchronization needs to occur between, no synchronization is not necessary to use synchronized, such as read-only data.
  4. The disadvantage of using synchronized is very inefficient, because the competition for the right to perform the operation after CPU lock release and release locks are very resource-intensive.

Guess you like

Origin www.cnblogs.com/hetangyuese/p/11564039.html