Deep understanding of the Synchronized keyword in Java _java

Source: Internet
Author: User
Tags modifier object object thread class

The Synchronized keyword, which represents the lock on this method, is equivalent to checking that any thread a runs to this method every time it has a thread B (or C d, etc.) that is using this method, and so on, with the thread B (or C D after running this method and then running this thread A, if not, run it directly including two uses: Synchronized method and synchronized block.

1. Synchronized method:
Declare the Synchronized method by adding the Synchronized keyword to the method declaration. Such as:

Copy Code code as follows:

Public synchronized void Accessval (int newval);

The Synchronized method Controls access to class member variables: Each class instance corresponds to a lock, each synchronized method must obtain a lock that invokes the class instance of the method to execute, otherwise the owning thread is blocked, and once the method is executed, the lock is exclusive until the lock is released when the method returns , the blocked thread can then get the lock and re-enter the executable state. This mechanism ensures that at the same time for each class instance, at most only one of the member functions declared as synchronized is in the executable state (since at most one can obtain the lock of that class instance),  This effectively avoids the access violation of class member variables (as long as all possible methods of accessing class member variables are declared as synchronized).  In Java, not just the class instance, each class also corresponds to a lock, so we can also declare the static member function of the class as synchronized to control its access to the static member variables of the class. The flaw of the Synchronized method: If a large method is declared as synchronized, it will greatly affect efficiency, typically, if the thread class method run () is declared as synchronized, because it is running throughout its lifetime, Therefore, the invocation of any synchronized method in this class will never succeed. Of course, we can do this by putting the code that accesses the class member variable into a specialized method, declaring it as synchronized, and tuning it in the main method to solve the problem, but Java provides us with a better solution, which is the synchronized block.

2. Synchronized BLOCK:
Declare synchronized block by synchronized keyword. The syntax is as follows:

Copy Code code as follows:

Synchronized (SyncObject)
{
Code that allows access control
}

A synchronized block is a block of code in which the code must obtain the lock of the object SyncObject (as described previously, can be a class instance or Class), and the specific mechanism is described in the previous instance. Because you can target arbitrary blocks of code, and can arbitrarily specify locked objects, so flexibility is high.

Some understanding of the synchronized (this)
First, when two concurrent threads access the synchronized (this) synchronized code block in the same object objects, only one thread can be executed at a time. Another thread must wait until the current thread finishes executing the code block before executing the code block.

Second, when a thread accesses a synchronized (this) synchronization code block of object, access to all other synchronized (this) synchronized code blocks in object is blocked.

Third, however, when a thread accesses a synchronized (this) synchronization code block of object, another thread can still access parts of the object except the synchronized (this) synchronization code block.

The third example also applies to other synchronized code blocks. That is, when a thread accesses a synchronized (this) synchronization code block of object, it obtains the object lock of the objects. As a result, access to all of the synchronization code portions of the object object by other threads is temporarily blocked.

The above rules apply to other object locks as well.

A simple example of synchronized

Copy Code code as follows:

public class Textthread
{
/**
* @param args
*/
public static void Main (string[] args)
{
TODO automatically generate method stubs
Txtthread tt = new Txtthread ();
New Thread (TT). Start ();
New Thread (TT). Start ();
New Thread (TT). Start ();
New Thread (TT). Start ();
}
}
Class Txtthread implements Runnable
{
int num = 100;
String str = new string ();
public void Run ()
{
while (true)
{
Synchronized (str)
{
if (num>0)
{
Try
{
Thread.Sleep (10);
}
catch (Exception e)
{
E.getmessage ();
}
System.out.println (Thread.CurrentThread (). GetName () + "This is" + num--);
}
}
}
}
}

In the above example in order to create a time difference, that is, the chance of error, the use of Thread.Sleep Java for multithreading support and synchronization mechanism by popular, it seems that the use of the Synchronized keyword can easily solve the problem of multithreading shared data synchronization. What's going on? --also have to synchronized the role of the key words to understand the conclusion.

In general, the Synchronized keyword can be used as a modifier of a function, or as a statement within a function, which is usually a synchronized method and a block of synchronized statements. In the finer categories, synchronized can be used for instance variables, object reference (reference), static functions, and class literals (class name literal constants). Before we further elaborate, we need to be clear on a few points:

A Whether the Synchronized keyword is added to a method or an object, the lock it obtains is an object rather than a piece of code or function as a lock-and the synchronization method is likely to be accessed by objects of other threads.

B Each object has only one lock (lock) associated with it.

C To achieve synchronization is a very large system overhead as a cost, and may even cause deadlock, so try to avoid unnecessary synchronization control.

Next, discuss the impact of synchronized on the code, assuming that P1, P2 are different objects of the same class, which define the synchronization blocks or synchronization methods for the following situations, P1, P2 can call them.

1. When you treat synchronized as a function modifier, the sample code is as follows:

Copy Code code as follows:

Public synchronized void Methodaaa ()
{
...
}

This is also the synchronization method, then synchronized locked is what object? It locks a call to this synchronization method object. That is, when an object P1 the synchronization method in a different thread, they form a mutex that achieves the effect of synchronization. But another object generated by the class that this object belongs to P2 can invoke the method that was added to the Synchronized keyword arbitrarily. The example code above is equivalent to the following code:

Copy Code code as follows:

public void Methodaaa ()
{
Synchronized (this)//(1)
{
.....
}
}

(1) What does this refer to? It refers to the object that invokes this method, such as P1. The visible synchronization method is essentially a synchronized action on the object reference. -The thread that gets the lock on the P1 object can invoke the P1 synchronization method, and for P2, P1 This lock has nothing to do with it, and the program may be able to get rid of the synchronization mechanism in this situation, resulting in data chaos.

2. Sync block, sample code as follows:

Copy Code code as follows:

public void method3 (Someobject so)
{
Synchronized (SO)
{
.....
}
}

Then the lock is the object of so, and whoever gets the lock can run the code it controls. When there is a clear object as a lock, you can write the program, but when there is no clear object as a lock and just want to synchronize a piece of code, you can create a special instance variable (it has to be an object) to act as a lock:

Copy Code code as follows:

Class Foo implements Runnable
{
Private byte[] lock = new Byte[0]; Special instance variables
public void MethodA ()
{
Synchronized (lock) {//...}
}
.....
}

Note: A 0-length byte array object is created more economically than any object--view compiled bytecode: A 0-length byte[] object takes only 3 opcode, while object lock = new Object () requires 7 rows of opcode.

3. The synchronized is applied to the static function, and the sample code is as follows:

Copy Code code as follows:

Class Foo
{
Public synchronized static void Methodaaa ()//synchronous static function
{
....
}
public void methodbbb ()
{
Synchronized (Foo.class)//class literal (class name literal constant)
}
}

The METHODBBB () method in the code is to use class literal as a lock, and it produces the same effect as the synchronized static function, and the lock is special, the class that the object that is currently calling the method belongs to (class, Instead of being a specific object generated by this class.

Remember in the book "Effective Java" that the Foo.class and P1.getclass () used as a synchronous lock is not the same, can not use P1.getclass () to achieve the purpose of locking this class. P1 refers to objects that are generated by the Foo class. It can be inferred that if a class has defined a synchronized static function A and also defines a synchronized instance function B, then the same object obj of this class will not constitute a synchronization when accessing A and B two methods, respectively, in multiple threads. Because their locks are not the same. The lock of a method is the object of obj, and the lock of B is the class that obj belongs to.

The summary is as follows:

Figuring out which object the synchronized is locking can help us design more secure multithreaded programs. There are also some techniques that will make it more secure to synchronize access to shared resources: 1. Define private instance variable + its get method instead of defining public/protected instance variables. If you define a variable as public, the object can get it directly and change it in the outside world 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 ArrayList, the above method is still unsafe, because when an external object gets a reference to the instance object through the Get method and points it to another object, the private variable is changed, It's dangerous. At this point you need to synchronize the Get method with synchronized, and return only the Clone () of the private object-so that the caller gets the reference to the copy of the object   More commonly used are: Collections.synchronizedmap (new HashMap ()), of course, this map is the life in the class global variable, is a thread-safe HashMap, The application of the web is common to all web containers, so use thread safety to ensure that the data is correct.

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.