Java keyword synchronized detailed
Blog Category:
Java Multithreading thread Internet manufacturing
The Synchronized keyword, which represents this method of locking, is equivalent to checking that there is no other thread B (or C d, etc.) that is using this method each time the thread a runs to this method, some of which are waiting for thread B (or C D) Run this method before running this thread A, no, run it directly consists of two usages: the Synchronized method and the synchronized block.
1. Synchronized method:
Declare the Synchronized method by adding the Synchronized keyword to the method declaration. Such as:
Public synchronized void Accessval (int newval);
The Synchronized method Controls access to class member variables: Each class instance corresponds to a lock, and each synchronized method must obtain a lock on the class instance that invokes the method to execute, otherwise the owning thread is blocked, and once the method executes, the lock is exclusive until the lock is released from the method return , 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 one of its member functions declared as synchronized is in an executable state (since at most one can obtain the corresponding lock for that class instance), This effectively avoids access violations of class member variables (as long as all methods that may access the class member variable are declared as synchronized).
In Java, not only class instances, 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 static member variables of the class.
The flaw of the Synchronized method: Declaring a large method as synchronized will greatly affect efficiency, typically if the method run () of the thread class is declared as synchronized, because it is running throughout the lifetime of the threads, As a result, the call to any synchronized method in this class will never succeed. Of course we can put the code that accesses the class member variable into a specialized method, declare it as synchronized, and use it in the main method to solve the problem, but Java provides us with a better solution, that is, the synchronized block.
2. Synchronized BLOCK:
Declare the synchronized block with the Synchronized keyword. The syntax is as follows:
Synchronized (SyncObject) {
Code that allows access control
}
The synchronized block is a block of code in which the code must obtain an object SyncObject (as previously described, which can be a class instance or Class) to execute, as described in the previous mechanism. Because it can be arbitrary code block, and can arbitrarily specify the locked object, it is more flexible.
Some understanding of synchronized (this)
First, when two concurrent threads access the same object in the synchronized (this) synchronization code block, only one thread can be executed within a single time. The other thread must wait for the current thread to finish executing the block before it can execute the code block.
Second, when a thread accesses one synchronized (this) of an object to synchronize a block of code, other threads will block access to all other synchronized (this) synchronized code blocks in object.
Third, however, when a thread accesses one of the synchronized (this) synchronization blocks of object, another thread can still access the part of the object except for the synchronized (this) synchronization code block.
The third example also applies to other synchronous blocks of code. That is, when a thread accesses a synchronized (this) of object to synchronize a block of code, it obtains the object lock of the objects. As a result, other threads are temporarily blocking access to all of the synchronization code portions of the object.
The above rules apply to other object locks as well.
A simple example of synchronized
public class Textthread {
/** * @param args */public static void main (string[] args) {//TODO auto-Generate method stub 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 () {if (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, which is the chance of error, the use of Thread.Sleep (10)
Java support for multithreading and synchronization mechanism by everyone's favorite, it seems that the use of the Synchronized keyword can easily solve the multi-threaded shared data synchronization problem. What's going on? --you have to have an in-depth understanding of the role of the Synchronized keyword.
In general, the Synchronized keyword can be used as a modifier of a function, or as a statement within a function, that is, a synchronous method and a synchronous statement block. In the case of finer classifications, synchronized can be used for instance variables, object reference, static functions, and class literals (literal constants of classes).
Before further elaboration, we need to make a few clear points:
A Regardless of whether the Synchronized keyword is added to a method or an object, the lock it obtains is an object, not a piece of code or function as a lock-and the synchronization method is likely to be accessed by other threads ' objects.
B Each object has only one lock (lock) associated with it.
C The implementation of synchronization is a big cost to the system, and may even cause deadlocks, so try to avoid unnecessary synchronization control.
Next, we discuss the effects of synchronized on the code in different places:
Suppose that P1, P2 is a different object of the same class, and this class defines a synchronization block or a synchronization method for the following situations, and P1, 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, then which object is synchronized locked? It is locked by calling this synchronization method object. That is, when an object P1 the synchronization method in a different thread, it creates mutual exclusion between them and achieves the effect of synchronization. However, another object generated by the class that this object belongs to P2 can call this method of adding the Synchronized keyword arbitrarily.
The example code above is equivalent to the following code:
public void Methodaaa ()
{
Synchronized (this)//(1)
{
.....
}
}
(1) What is this referring to? It refers to the object that invokes the method, such as P1. The visible synchronization method is essentially the synchronized action on object reference. --the thread that got the P1 object lock can call P1 's synchronous method, and for P2, P1 This lock has nothing to do with it, and the program may get rid of the control of synchronization mechanism in this situation, causing data confusion: (
2. Synchronization block, the sample code is as follows:
public void method3 (Someobject)
{
Synchronized (SO)
{ //..... }
}
At this point, the lock is the so object, who gets the lock who can run the code it controls. When there is a definite object as the lock, you can write the program, but when there is no explicit object as a lock, just want to let a piece of code synchronization, you can create a special instance variable (it has to be an object) to act as a lock:
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 will be more economical to create than any object-view compiled bytecode: generates a 0-length byte[] object with only 3 opcode, and object lock = new Object () requires 7 lines of opcode.
3. The synchronized action is applied to the static function, and the sample code is 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 the case of the class literal as a lock, which produces the same effect as the synchronous static function, and the resulting lock is very special, which is the class that the object that is currently calling this method belongs to (class, Instead of being a specific object produced by this class.
Remember in the "effective Java" book saw that the Foo.class and P1.getclass () used for synchronous lock is not the same, can not use P1.getclass () to achieve the purpose of the lock class. P1 refers to objects produced by the Foo class.
It can be inferred that if a synchronized static function A is defined in a class, and a synchronized instance function B is also defined, then the same object of this class, obj, accesses A and B two methods in multiple threads, which does not constitute synchronization. Because their locks are not the same. The lock of the 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 locks on can help us design more secure multithreaded programs.
There are also some tricks that will make it more secure to synchronize access to shared resources:
1. Define the private instance variable + its get method instead of defining the public/protected instance variable. If a variable is defined as public, the object can get it directly from the outside world by bypassing the control of the synchronization method and altering it. This is also one of the standard implementations of JavaBean.
2. If the instance variable is an object, such as an array or ArrayList, then 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, Wouldn't it be dangerous. At this point, you need to add the Get method to the synchronized synchronization, and only the Clone () of the private object is returned-so that the caller gets a reference to the object copy.
Also, the more commonly used are: Collections.synchronizedmap (new HashMap ()), of course, this map is life in the class of global variables, 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.
Partial excerpt from the Internet, thanks to the author
Java keyword synchronized detailed