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
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 )
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
Scenarios
In multiple threads, we can be achieved by locking To achieve resource sharing; synchronized block is not recommended logic is too complex
Lock
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
principle
Lock lock unlock common method of implementation class ReentrantLock, ReadWriteLock the like, which basically relies AQS (AbstractQueuedSynchronizer) provided.
to sum up
- 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.
- To use synchronized, there must be two or more threads. Single-threaded use does not make sense, but also to reduce the efficiency.
- To use synchronized, thread synchronization needs to occur between, no synchronization is not necessary to use synchronized, such as read-only data.
- 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.