Java synchronization mechanism-synchronized

Source: Internet
Author: User
Java's multi-thread support and synchronization mechanism seems to use the synchronized keyword to easily solve the problem of multi-thread shared data synchronization. What is the problem? -You must have an in-depth understanding of the role of the synchronized keyword.
In general, the synchronized keyword can be used as the modifier of the function or as the statement in the function, that is, the synchronization method and synchronization statement block. if further classification is performed, synchronized can act on instance variables, object reference, static functions, and class literals (literal constants of class names.
Before proceeding, we need to clarify the following points:
A. no matter whether the synchronized keyword is added to the method or object, the lock it acquires is an object, instead of using a piece of code or function as a lock-and the synchronization method is likely to be accessed by objects in other threads.
B. Each object has only one lock associated with it.
C. Implementing synchronization requires a large amount of system overhead as a cost, and may even cause deadlocks. Avoid unnecessary synchronization control as much as possible.
Next we will discuss the impact of synchronized on code in different places:
Assume that P1 and P2 are different objects of the same class. This class defines synchronization blocks or Synchronization Methods in the following situations. P1 and P2 can call them.
1. When synchronized is used as a function modifier, the sample code is as follows:
Public synchronized void methodaaa ()
{
//....
}
This is the synchronization method. Which object is synchronized locked at this time? The lock is to call this synchronization method object. that is to say, when an object P1 executes this synchronization method in different threads, they are mutually exclusive to achieve synchronization. however, the P2 object generated by the class to which this object belongs can call the method with the synchronized keyword.
The above sample code is equivalent to the following code:
Public void methodaaa ()
{
Synchronized (this) // (1)
{
//.....
}
}
(1) What does this mean? It refers to the object that calls this method. For example, P1. the visible synchronization method essentially acts synchronized on the object reference. -- the thread that obtains the P1 object lock can call the synchronization method of P1. For P2, the P1 lock has nothing to do with it, in this case, the program may also get rid of the control of the synchronization mechanism, resulting in data confusion :(
2. Synchronization block. The sample code is as follows:
Public void method3 (someobject so)
{
Synchronized (SO)
{
//.....
}
}
In this case, the lock is the so object. Whoever gets the lock can run the code it controls. when a specific object is used as the lock, you can write the program in this way, but when there is no clear object as the lock, just want to synchronize a piece of code, you can create a special instance variable (which must be an object) to act as a lock:
Class Foo implements runnable
{
Private byte [] Lock = new byte [0]; // special instance variable
Public void methoda ()
{
Synchronized (LOCK ){//... }
}
//.....
}
Note: creating a zero-Length byte array object is more economical than any other object-view the compiled bytecode: only three operation codes are required for generating a zero-Length byte [] object, object lock = new object () requires 7 lines of operation code.
3. apply synchronized to the static function. The sample code is as follows:
Class foo
{
Public synchronized static void methodaaa () // synchronized static function
{
//....
}
Public void methodbbb ()
{
Synchronized (FOO. Class) // class literal (Class Name literal constant)
}
}
The methodbbb () method in the Code uses class literal as the lock. It produces the same effect as the synchronized static function, and the obtained lock is very special, is the class of the object currently calling this method (class, instead of a specific object generated by this class ).
I remember seeing Foo in objective Java. class and p1.getclass () are used for synchronization locks. p1.getclass () cannot be used to lock this class. p1 refers to the object generated by the foo class.
It can be inferred that if a class defines a static function a of synchronized, it also defines the instance function B of synchronized, when the same object OBJ of this class accesses Methods A and B in multiple threads, the synchronization is not formed because their locks are different. the lock of method A is the object OBJ, and the lock of Method B is the class to which OBJ belongs.
Summary:
Figuring out which object synchronized is locked can help us design safer multi-threaded programs.
There are also some tips to make our synchronized access to shared resources more secure:
1. define the private instance variable + its get method, instead of the public/protected instance variable. if a variable is defined as public, the object can directly obtain it and change it by bypassing the control of the synchronization method. this is also one of the standard implementations of JavaBean.
2. if the instance variable is an object, such as an array or an arraylist, the above method is still insecure, because after the External Object obtains the reference of this instance object through the get method, if you point it to another object, the private variable changes, and it is not dangerous. at this time, you need to add the get method and synchronized synchronization, and only return the clone () of this private object-in this way, the caller obtains the reference of the object copy.
Some Understanding of synchronized (this)
1. When two concurrent threads access the synchronized (this) synchronization code block of the same object, only one thread can be executed within a time period. the other thread must wait until the current thread finishes executing this code block before executing this code block.
2. However, when a thread accesses a synchronized (this) synchronization code block of the object, the other thread can still access the non-synchronized (this) synchronization code block of the object.
3. When a thread accesses a synchronized (this) synchronization code block of the object, other threads perform synchronization on all other synchronized (this) access to the synchronization code block will be blocked.
4. The third example also applies to other synchronous code blocks. that is to say, when a thread accesses a synchronized (this) synchronization code block of an object, it obtains the object lock of this object. as a result, access by other threads to all the synchronized code parts of the object is temporarily blocked.
5. The above rules apply to other Object locks.
Example:
1. When two concurrent threads access the synchronized (this) synchronization code block of the same object, only one thread can be executed within a time period. the other thread must wait until the current thread finishes executing this code block before executing this code block.
Package ths;
Public class thread1 implements runnable {
Public void run (){
Synchronized (this ){
For (INT I = 0; I <5; I ++ ){
System. Out. println (thread. currentthread (). getname () + "synchronized loop" + I );
}
}
}
Public static void main (string [] ARGs ){
Thread1 T1 = new thread1 ();
Thread TA = new thread (T1, "");
Thread TB = new thread (T1, "B ");
Ta. Start ();
TB. Start ();
}
}
Result:
A Synchronized loop 0
A Synchronized loop 1
A Synchronized loop 2
A Synchronized loop 3
A Synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4
2. However, when a thread accesses a synchronized (this) synchronization code block of the object, the other thread can still access the non-synchronized (this) synchronization code block of the object.
Package ths;
Public class thread2 {
Public void m4t1 (){
Synchronized (this ){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ":" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
}
Public void m4t2 (){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ":" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
Public static void main (string [] ARGs ){
Final thread2 myt2 = new thread2 ();
Thread T1 = new thread (
New runnable (){
Public void run (){
Myt2.m4t1 ();
}
}, "T1"
);
Thread t2 = new thread (
New runnable (){
Public void run (){
Myt2.m4t2 ();
}
}, "T2"
);
T1.start ();
T2.start ();
}
}
Result:
T1: 4
T2: 4
T1: 3
T2: 3
T1: 2
T2: 2
T1: 1
T2: 1
T1: 0
T2: 0
3. When a thread accesses a synchronized (this) synchronization code block of the object, other threads perform synchronization on all other synchronized (this) access to the synchronization code block will be blocked.
// Modify the thread2.m4t2 () method:
Public void m4t2 (){
Synchronized (this ){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ":" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
}
Result:
T1: 4
T1: 3
T1: 2
T1: 1
T1: 0
T2: 4
T2: 3
T2: 2
T2: 1
T2: 0
4. The third example also applies to other synchronous code blocks. that is to say, when a thread accesses a synchronized (this) synchronization code block of an object, it obtains the object lock of this object. as a result, access by other threads to all the synchronized code parts of the object is temporarily blocked.
// Modify thread2.m4t2 () as follows:
Public synchronized void m4t2 (){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ":" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
Result:
T1: 4
T1: 3
T1: 2
T1: 1
T1: 0
T2: 4
T2: 3
T2: 2
T2: 1
T2: 0
5. The above rules apply to other Object locks:
Package ths;
Public class thread3 {
Class inner {
Private void m4t1 (){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ": inner. m4t1 () =" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
Private void m4t2 (){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ": inner. m4t2 () =" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
}
Private void m4t1 (inner ){
Synchronized (inner) {// use the object lock
Inner. m4t1 ();
}
}
Private void m4t2 (inner ){
Inner. m4t2 ();
}
Public static void main (string [] ARGs ){
Final thread3 myt3 = new thread3 ();
Final inner = myt3.new inner ();
Thread T1 = new thread (
New runnable (){
Public void run (){
Myt3.m4t1 (inner );
}
}, "T1"
);
Thread t2 = new thread (
New runnable (){
Public void run (){
Myt3.m4t2 (inner );
}
}, "T2"
);
T1.start ();
T2.start ();
}
}
Result:
Although thread T1 obtains the object lock on the inner, thread T2 accesses the non-synchronous part of the same inner, so the two threads do not interfere with each other.
T1: inner. m4t1 () = 4
T2: inner. m4t2 () = 4
T1: inner. m4t1 () = 3
T2: inner. m4t2 () = 3
T1: inner. m4t1 () = 2
T2: inner. m4t2 () = 2
T1: inner. m4t1 () = 1
T2: inner. m4t2 () = 1
T1: inner. m4t1 () = 0
T2: inner. m4t2 () = 0
Now add synchronized before inner. m4t2:
Private synchronized void m4t2 (){
Int I = 5;
While (I --> 0 ){
System. Out. println (thread. currentthread (). getname () + ": inner. m4t2 () =" + I );
Try {
Thread. Sleep (500 );
} Catch (interruptedexception IE ){
}
}
}
Result:
Although thread t1 and t2 access two unrelated parts of the same inner object, because T1 first obtains the object lock on inner, so T2 has access to inner. m4t2 () access is also blocked, because m4t2 () is a synchronization method in inner.
T1: inner. m4t1 () = 4
T1: inner. m4t1 () = 3
T1: inner. m4t1 () = 2
T1: inner. m4t1 () = 1
T1: inner. m4t1 () = 0
T2: inner. m4t2 () = 4
T2: inner. m4t2 () = 3
T2: inner. m4t2 () = 2
T2: inner. m4t2 () = 1
T2: inner. m4t2 () = 0

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.