In concurrent environments, you can consider the use of lock mechanisms when resolving shared resource conflict issues. 1. Object Lock
All objects automatically contain a single lock.
The JVM is responsible for tracking the number of times an object is locked. If an object is unlocked, its count becomes 0. When a task (thread) locks an object for the first time, the count changes to 1. The count increments whenever this same task (thread) Gets a lock on this object.
Only the task (thread) that obtains the lock first can continue to acquire multiple locks on the object.
Every time a task leaves a synchronized method, the Count decrements, and when the count is 0, the lock is completely freed, and other tasks can use the resource at this time. 2. Class Lock
For a synchronous static method/static variable mutex, the static method and the static variable in memory are only one copy of the class, regardless of how many times it is instantiated. So, once a static method is declared as synchronized. All instantiated objects of this class call this method, sharing the same lock, which we call the class lock. Once a static variable is used as the mutex of the synchronized block. When you enter this synchronization area, you first get the object lock for this static variable.
A concept derived from the above synchronous static method is the class lock. In fact, there is no class lock in the system. When a synchronous static method is invoked, the system acquires the object lock that represents the class object of the class.
You can try to get a class lock in the following ways
Synchronized (Xxx.class) {...}
Synchronized (class.forname ("xxx")) {...}
To get both types of locks at the same time, while getting class locks and object locks is permissible and does not cause any problems, it is important to note when using class locks that a deadlock is generated when a class lock is generated, because each class can only generate a class instance object in memory. 3. Synchronized Sync block 3.1. Sync to a single object lock
When a synchronized block is used, all tasks (threads) can only be mutually exclusive into these synchronized blocks if the synchronized blocks under the method are synchronized to a lock on an object.
Resource1.java demonstrates that three threads, including the main thread, attempt to enter a synchronized block of three different methods of a class, although these synchronized blocks are in different methods, but because they are synchronized to the same object (the current object synchronized (this)), So the approach to them is still mutually exclusive.
Resource1.java
Package com.zj.lock;
Import Java.util.concurrent.TimeUnit;
public class Resource1 {public void F () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in F ()"); Synchronized (this) {for (int i = 0; i < 5; i++) {System.out.println (Thread.currentthrea
D (). GetName () + ": Synchronized in F ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
{}}} public void G () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": Not synchronized in G ()"); Synchronized (this) {for (int i = 0; i < 5; i++) {System.out.println (Thread.currentthrea D(). GetName () + ": Synchronized in G ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
{}}} is public void H () {//The other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in H ()"); Synchronized (this) {for (int i = 0; i < 5; i++) {System.out.println (Thread.currentthrea
D (). GetName () + ": Synchronized in H ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace (); }}} public static void Main (string[] args) {final Resource1 rs = new Reso
Urce1 ();
New Thread () { public void Run () {rs.f ();
}}.start ();
New Thread () {public void run () {RS.G ();
}}.start ();
Rs.h (); }
}
Results:
Thread-0:not synchronized in F ()
Thread-0:synchronized in F ()
Main:not synchronized in H ()
Thread-1:not synchronized in G ()
Thread-0:synchronized in F ()
Thread-0:synchronized in F ()
Thread-0:synchronized in F ()
Thread-0:synchronized in F ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Main:synchronized in H ()
Main:synchronized in H ()
Main:synchronized in H ()
Main:synchronized in H ()
Main:synchronized in H () 3.2. Synchronizing to multiple object locks
Resource1.java demonstrated that three threads (including the main thread) attempted to enter a synchronized block of three different methods of a class that were in different methods and synchronized to three different objects (this), Synchronized (SyncObject1), synchronized (SYNCOBJECT2)), so access to critical resources in their methods is independent.
Resource2.java
Package com.zj.lock;
Import Java.util.concurrent.TimeUnit;
public class Resource2 {private Object SyncObject1 = new Object ();
Private Object SyncObject2 = new Object ();
The public void f () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in F ()"); Synchronized (this) {for (int i = 0; i < 5; i++) {System.out.println (Thread.currentthrea
D (). GetName () + ": Synchronized in F ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
{}}} public void G () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": Not synchronized in G ()"); Synchronized (SyncObject1) {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread ()). GetName ()
+ ": Synchronized in G ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
{}}} is public void H () {//The other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in H ()"); Synchronized (SYNCOBJECT2) {for (int i = 0; i < 5; i++) {System.out.println (Thread.curre
Ntthread (). GetName () + ": Synchronized in H ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace (); Public sta in}}}tic void Main (string[] args) {final Resource2 rs = new Resource2 ();
New Thread () {public void run () {rs.f ();
}}.start ();
New Thread () {public void run () {RS.G ();
}}.start ();
Rs.h (); }
}
Results:
Thread-0:not synchronized in F ()
Thread-0:synchronized in F ()
Main:not synchronized in H ()
Main:synchronized in H ()
Thread-1:not synchronized in G ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G () 4. Lock Object Locks
In addition to using synchronized, you can use the lock object to create a critical section. The demonstration effect of Resource3.java with the Resource1.java;resource4.java demonstration effect with Resource2.java.
Resource3.java
Package com.zj.lock;
Import Java.util.concurrent.TimeUnit;
Import Java.util.concurrent.locks.Lock;
Import Java.util.concurrent.locks.ReentrantLock;
public class Resource3 {private lock lock = new Reentrantlock ();
The public void f () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in F ()");
Lock.lock ();
try {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread (). GetName ()
+ ": Synchronized in F ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
}}} finally {Lock.unlock ();
} public void G () {//Other operations should is locked ... System.out.println (THREAD.CURRENTTHRead (). GetName () + ": Not synchronized in G ()");
Lock.lock ();
try {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread (). GetName ()
+ ": Synchronized in G ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
}}} finally {Lock.unlock ();
The public void H () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in H ()");
Lock.lock ();
try {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread (). GetName ()
+ ": Synchronized in H ()");
try {TimeUnit.SECONDS.sleep (3); } catch (Interruptedexception e) {e.printstacktrace ();
}}} finally {Lock.unlock ();
} public static void Main (string[] args) {final Resource3 rs = new Resource3 ();
New Thread () {public void run () {rs.f ();
}}.start ();
New Thread () {public void run () {RS.G ();
}}.start ();
Rs.h (); }
Results:
Thread-0:not synchronized in F ()
Thread-0:synchronized in F ()
Main:not synchronized in H ()
Thread-1:not synchronized in G ()
Thread-0:synchronized in F ()
Thread-0:synchronized in F ()
Thread-0:synchronized in F ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Main:synchronized in H ()
Main:synchronized in H ()
Main:synchronized in H ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Thread-1:synchronized in G ()
Resource4.java
Package com.zj.lock;
Import Java.util.concurrent.TimeUnit;
Import Java.util.concurrent.locks.Lock;
Import Java.util.concurrent.locks.ReentrantLock;
public class Resource4 {private Lock lock1 = new Reentrantlock ();
Private Lock Lock2 = new Reentrantlock ();
Private Lock Lock3 = new Reentrantlock ();
The public void f () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in F ()");
Lock1.lock ();
try {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread (). GetName ()
+ ": Synchronized in F ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
}}} finally {Lock1.unlock (); }} public void G (){///Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": Not synchronized in G ()");
Lock2.lock ();
try {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread (). GetName ()
+ ": Synchronized in G ()");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
}}} finally {Lock2.unlock ();
The public void H () {//Other operations should is locked ...
System.out.println (Thread.CurrentThread (). GetName () + ": not synchronized in H ()");
Lock3.lock ();
try {for (int i = 0; i < 5; i++) {System.out.println (Thread.CurrentThread (). GetName () + ": SynchroNized in H () ");
try {TimeUnit.SECONDS.sleep (3);
catch (Interruptedexception e) {e.printstacktrace ();
}}} finally {Lock3.unlock ();
} public static void Main (string[] args) {final Resource4 rs = new Resource4 ();
New Thread () {public void run () {rs.f ();
}}.start ();
New Thread () {public void run () {RS.G ();
}}.start ();
Rs.h (); }
}
Results:
Thread-0:not synchronized in F ()
Thread-0:synchronized in F ()
Main:not synchronized in H ()
Main:synchronized in H ()
Thread-1:not synchronized in G ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
Thread-0:synchronized in F ()
Main:synchronized in H ()
Thread-1:synchronized in G ()
In addition, the Reentrantlock can be timed and polling lock acquisition mode implemented by the Trylock method.
public boolean trylock (); Equivalent to Trylock (0, Timeunit.seconds), asking whether the lock public
boolean trylock (long timeout, timeunit unit) can be obtained
throws Interruptedexception //timeout-time to wait for a lock, the time unit of the Unit-timeout parameter
5. The difference between synchronized and lock:
Lock locks are implemented through code, and synchronized is implemented at the JVM level.
Synchronized if the method block throws an exception when the lock is locked, the JVM automatically releases the lock and does not cause the thread to deadlock because of an exception without releasing the lock. But lock will not be able to enjoy the JVM to bring automatic functionality, when the exception must be in the finally release the lock, otherwise it would cause deadlock.
In the case of resource competition is not very intense, occasionally there will be synchronization situations, synchronized is very appropriate. The reason is that the compiler usually optimizes the synchronize as much as possible, and the readability is very good, regardless of how many programmers use more than 5 thread packs to understand it. Reentrantlock:
Reentrantlock provides a variety of synchronization, such as time-limited synchronization, can be interrupt synchronization (synchronized synchronization is not interrupt), and so on. In the case of less competitive resources, performance is slightly more than synchronized. But when the synchronization is very intense, the performance of synchronized can drop dozens of times times. And Reentrantlock can still remain normal. Atomic:
Similar to the above, in a less intense situation, performance than synchronized slightly worse, and intense time, but also to maintain the normal. In the intense time, the atomic performance will be superior to reentrantlock about one times. But there is a drawback, that is, only one value can be synchronized, a piece of code can only appear a atomic variable, more than one synchronization is invalid. Because he can't sync between multiple atomic.
For a detailed distinction between synchronized and lock, see http://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html.
Turn from: http://blog.csdn.net/ymeng_bupt/article/details/6826936