Five, mutual exclusion synchronization
Java provides two locking mechanisms to control mutually exclusive access to shared resources by multiple threads, the first being the synchronized of the JVM implementation, and the other being the reentrantlock of the JDK implementation.
1.1 synchronized1. Synchronizing a block of code
Public void func () { synchronized (this) { // ... }}
It only works on the same object, and if you call a synchronous block of code on two objects, it will not be synchronized.
For the following code, two threads were executed using Executorservice, and because the synchronous code block of the same object was called, the two threads were synchronized, and when one thread entered the synchronous statement block, another thread had to wait.
Public classSynchronizedexample { Public voidfunc1 () {synchronized( This) { for(inti = 0; I < 10; i++) {System.out.print (i+ " "); } } }} Public Static voidMain (string[] args) {synchronizedexample e1=Newsynchronizedexample (); Executorservice Executorservice=Executors.newcachedthreadpool (); Executorservice.execute (()-e1.func1 ()); Executorservice.execute (()-e1.func1 ());}0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
For the following code, two threads call a synchronous block of code for different objects, so the two threads do not need to be synchronized. As you can see from the output, two threads cross execution.
Public Static void Main (string[] args) { new synchronizedexample (); New synchronizedexample (); = Executors.newcachedthreadpool (); e1.func1 ()); e2.func1 ());} 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
2. Synchronizing a method
Public synchronized void func () { // ... }
It is used as a synchronous code block for the same object.
3. Synchronization of a class
Public void func () { synchronized (synchronizedexample. Class) { // ... }}
Acts on the entire class, which means that two threads call this synchronization statement on different objects of the same class and synchronize.
Public classSynchronizedexample { Public voidFunc2 () {synchronized(Synchronizedexample.class) { for(inti = 0; I < 10; i++) {System.out.print (i+ " "); } } }} Public Static voidMain (string[] args) {synchronizedexample e1=Newsynchronizedexample (); Synchronizedexample E2=Newsynchronizedexample (); Executorservice Executorservice=Executors.newcachedthreadpool (); Executorservice.execute (()-E1.func2 ()); Executorservice.execute (()-E2.func2 ());}0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
4. Synchronizing a static method
Public synchronized Static void Fun () { // ... }
Acts on the entire class.
1.2 Reentrantlock
Reentrantlock is a lock in the Java.util.concurrent (J.U.C) package.
Public classLockexample {PrivateLock lock =NewReentrantlock (); Public voidfunc () {lock.lock (); Try { for(inti = 0; I < 10; i++) {System.out.print (i+ " "); } } finally{lock.unlock ();//ensure that the lock is released to avoid deadlocks. } }} Public Static voidMain (string[] args) {lockexample lockexample=Newlockexample (); Executorservice Executorservice=Executors.newcachedthreadpool (); Executorservice.execute (()-Lockexample.func ()); Executorservice.execute (()-Lockexample.func ());}0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
1.3 Comparison
implementation of Locks
The synchronized is implemented by the JVM, and Reentrantlock is implemented by the JDK.
Performance
The new version of Java has a lot of optimizations for synchronized, such as spin locks, and synchronized are roughly the same as Reentrantlock.
wait can be interrupted
When the thread holding the lock does not release the lock for a long time, the waiting thread can choose to discard the wait and handle other things instead.
Reentrantlock can be interrupted, and synchronized not.
Fair Lock
A fair lock is when multiple threads are waiting for the same lock, and the lock must be obtained sequentially in the order in which the locks are requested.
Synchronized in the lock is not fair, reentrantlock by default is also unfair, but can also be fair.
Lock binding multiple conditions
A reentrantlock can bind multiple Condition objects at the same time.
Use selection
Unless you need to use the advanced features of Reentrantlock, use synchronized first. This is because synchronized is a locking mechanism implemented by the JVM that natively supports it, while Reentrantlock is not supported by all JDK versions. and using synchronized does not have to worry about deadlocks without releasing locks, because the JVM ensures that the locks are released.
VI. Collaboration between threads
When multiple threads can work together to solve a problem, if some parts must be completed before other parts, then the thread needs to be reconciled.
1.4 Join ()
Calling the Join () method of another thread in the threads suspends the current thread instead of busy waiting until the target thread ends.
For the following code, although the B-line enters upgradeable is started, the B thread waits for the A-thread to end before it executes because it calls the join () method of the A thread in the B thread, so it finally ensures that the output of the A-thread precedes the output of the B-thread.
Public classJoinexample {Private classAextendsThread {@Override Public voidrun () {System.out.println (A); } } Private classBextendsThread {PrivateA; B (a a) { This. A =A; } @Override Public voidrun () {Try{a.join (); } Catch(interruptedexception e) {e.printstacktrace (); } System.out.println (B); } } Public voidTest () {A A=NewA (); b b=NewB (a); B.start (); A.start (); }} Public Static voidMain (string[] args) {Joinexample example=Newjoinexample (); Example.test ();} AB
1.5 Wait () notify () Notifyall ()
Calling Wait () causes the thread to wait for a condition to be satisfied, the thread waits for it to be suspended, and the other thread calls notify () or Notifyall () to wake the suspended thread when the other thread is running so that the condition is satisfied.
They all belong to part of Object, not Thread.
Can only be used in synchronous methods or synchronization control blocks, otherwise it will throw illegalmonitorstateexeception at run time.
During a wait () suspend, the thread releases the lock. This is because if the lock is not released, then other threads cannot enter the object's synchronization method or the synchronization control block, then notify () or notifyall () cannot be executed to wake the suspended thread, causing a deadlock.
Public classWaitnotifyexample { Public synchronized voidbefore () {System.out.println ("Before"); Notifyall (); } Public synchronized voidAfter () {Try{wait (); } Catch(interruptedexception e) {e.printstacktrace (); } System.out.println ("After"); }} Public Static voidMain (string[] args) {Executorservice Executorservice=Executors.newcachedthreadpool (); waitnotifyexample Example=Newwaitnotifyexample (); Executorservice.execute (()-Example.after ()); Executorservice.execute (()-Example.before ());} Beforeafter
Wait () and the sleep () the Difference
- Wait () is the method of Object, and sleep () is the static method of Thread;
- Wait () releases the lock, and sleep () does not.
1.6 await () signal () Signalall ()
The Condition class is provided in the Java.util.concurrent class library to enable thread coordination, and you can use the await () method on the Condition to make the thread wait, and the other thread calls the signal () or Signalall () method to wake the waiting Thread.
Await () is more flexible than wait (), which can specify the conditions to wait.
Use Lock to get a Condition object.
Public classAwaitsignalexample {PrivateLock lock =NewReentrantlock (); PrivateCondition Condition =lock.newcondition (); Public voidbefore () {lock.lock (); Try{System.out.println ("Before"); Condition.signalall (); } finally{lock.unlock (); } } Public voidAfter () {lock.lock (); Try{condition.await (); System.out.println ("After"); } Catch(interruptedexception e) {e.printstacktrace (); } finally{lock.unlock (); } }} Public Static voidMain (string[] args) {Executorservice Executorservice=Executors.newcachedthreadpool (); awaitsignalexample Example=Newawaitsignalexample (); Executorservice.execute (()-Example.after ()); Executorservice.execute (()-Example.before ());} Beforeafter
Java Concurrency 2--Advanced