When two or more two threads need to share resources, they need some way to determine that the resource is occupied by only one thread at a moment. The process to achieve this is called Synchronization (synchronization). As you can see, Java provides unique, language-level support for this.
The key to synchronization is the concept of enhancement (also called Semaphore semaphore). Enhancement is a mutex exclusive lock object, or mutex (mutex). At a given time, only one thread can get a pipe. When a thread needs to be locked, it must go into the pipe. All other threads attempting to enter a locked enhancement must hang until the first thread exits the pipe. These other threads are called waiting for a pipe. A thread that has a pipe can enter the same enhancement again if you wish.
If you've used synchronization in other languages such as C or C + +, you'll know it's a bit tricky to use. This is because many languages themselves do not support synchronization. Instead, for a synchronization thread, the program must take advantage of the operating system source language. Fortunately, Java is synchronized with language elements, and most of the synchronization-related complexities are eliminated.
You can synchronize your code in two ways. Both of these include the use of synchronized keywords, which are described below respectively.
Using the synchronization method
Synchronization in Java is simple, because all objects have implicit threads that correspond to them. The process of entering an object is called by the method that is modified by the Synchronized keyword. When a thread is inside a synchronous method, all other threads that attempt to invoke the same instance of the method (or other synchronization methods) must wait. To exit the pipe and discard control of the object to other waiting threads, the thread that owns the pipe only needs to be returned from the synchronization method.
To understand the need for synchronization, let's start with a simple example that should be used without synchronization. The following program has three simple classes. The first is CallMe, which has a simple method of call (). The call () method has a string parameter named Msg. The method attempts to print the MSG string inside the square brackets. The interesting thing is to call Thread.Sleep (1000) after calling call () to print the opening parenthesis and the MSG string, which causes the current thread to pause for 1 seconds.
The constructor for the next class, caller, references an instance of CallMe and a string, which are respectively in Target and MSG. The constructor also creates a new thread that invokes the run () method of the object. The thread starts immediately. The run () method of the caller class invokes the call () method of the CallMe instance target through the parameter msg string. Finally, the Synch class starts with a simple instance of creating a CallMe and three instances of caller with different message strings.
The same instance of CallMe is passed to each caller instance.
1 //This program was not synchronized.2 classCallme {3 voidCall (String msg) {4System.out.print ("[" +msg);5 Try {6Thread.Sleep (1000);7}Catch(interruptedexception e) {8System.out.println ("Interrupted");9 }TenSystem.out.println ("]"); One } A } - - classCallerImplementsRunnable { the String msg; - Callme Target; - Thread t; - PublicCaller (Callme Targ, String s) { +target =Targ; -msg =s; +t =NewThread ( This); A T.start (); at } - Public voidrun () { - Target.call (msg); - } - } - in classSynch { - Public Static voidMain (String args[]) { toCallme target =NewCallme (); +Caller Ob1 =NewCaller (Target, "Hello"); -Caller OB2 =NewCaller (Target, "Synchronized"); theCaller OB3 =NewCaller (Target, "world"); * //wait for threads to end $ Try {Panax Notoginseng Ob1.t.join (); - Ob2.t.join (); the Ob3.t.join (); +}Catch(interruptedexception e) { ASystem.out.println ("Interrupted"); the } + } -}
The output of the program is as follows:
Hello[synchronized[world]
]
]
In this example, by calling sleep (), the call () method allows the execution to transition to another thread. The result is a mixed output of three message strings. There is a method in the program that does not prevent three threads from calling the same method at the same time. This is a competition because three threads are contending for the completion method. The example uses sleep () to make the effect repetitive and obvious. In most cases, competition is more complex and unpredictable because you cannot determine when context conversions will occur. This causes the program to run normally and sometimes error.
To achieve the purpose of the above example, you must have the right to use call () consecutively. That is, at some point, you have to limit only one thread to dictate it. To do this, you simply precede the call () definition with the keyword synchronized, as follows:
1 class Callme {2 synchronized void Call (String msg) {3 ...
This prevents other threads from entering call () when one thread is using call (). After synchronized is added to call (), the program output is as follows:
[Hello]
[Synchronized]
[World]
Any time you have a method or multiple methods to manipulate an object's internal state in a multithreaded situation, you must use the Synchronized keyword to prevent the state from competing. Remember that once a thread enters the instance's synchronization method, no other thread can enter the same instance of the synchronization method. However, other unsynchronized methods of the instance can still be called.
Synchronization statements
Although creating a synchronization method inside a class created is a simple and efficient way to get synchronized, it is not valid at all times. The reason for this, please follow the thinking. Suppose you want to obtain synchronous access to a class object that is not designed for multithreaded access, that is, the class does not use the Synchronized method. Moreover, the class is not yourself, but a third party created, and you cannot get its source code. This way, you cannot add synchronized modifiers before the relevant method. How can I synchronize an object of this class? Fortunately, the solution is simple: you simply put the call to the method defined by this class in a synchronized block.
The following is the normal form of the synchronized statement:
1 synchronized (object) {2 // statements to be synchronized 3 }
Where object is a reference to the synchronized objects. If you want to synchronize only one statement, then no curly braces are required. A synchronization block ensures that a call to an object member method occurs only after the current thread has successfully entered an object pipe.
The following is a modified version of the previous program, using a synchronization block within the run () method:
1 //This program uses a synchronized block.2 classCallme {3 voidCall (String msg) {4System.out.print ("[" +msg);5 Try {6Thread.Sleep (1000);7}Catch(interruptedexception e) {8System.out.println ("Interrupted");9 }TenSystem.out.println ("]"); One } A } - - classCallerImplementsRunnable { the String msg; - Callme Target; - Thread t; - PublicCaller (Callme Targ, String s) { +target =Targ; -msg =s; +t =NewThread ( This); A T.start (); at } - - //Synchronize calls to call () - Public voidrun () { - synchronized(target) {//synchronized Block - Target.call (msg); in } - } to } + - classSynch1 { the Public Static voidMain (String args[]) { *Callme target =NewCallme (); $Caller Ob1 =NewCaller (Target, "Hello");Panax NotoginsengCaller OB2 =NewCaller (Target, "Synchronized"); -Caller OB3 =NewCaller (Target, "world"); the + //wait for threads to end A Try { the Ob1.t.join (); + Ob2.t.join (); - Ob3.t.join (); $}Catch(interruptedexception e) { $System.out.println ("Interrupted"); - } - } the}
Here, the call () method is not modified by synchronized. The synchronized is declared in the run () method of the caller class. This gives the same correct result in the previous example, because each thread waits for the previous thread to end before it runs.
Series Articles:
Java know how much (top)
Java know how much (interface) interface
Java knows how much (40) the difference between an interface and an abstract class
Java know how much (41) generic explanation
Java know how much (42) the range of generic wildcard characters and type parameters
Java know how much (43) Exception Handling Basics
Java know how much (44) exception type
Java know how much (45) uncaught exceptions
How much Java knows (the) use of try and catch
Java know how much (47) use of multiple catch statements
Java knows how much (in) the nesting of Try statements
Java know how much (a) throw: Exception throws
Java know how many () Java throws clauses
Java knows how many (or) finally
Java know how much (52) built-in exceptions
Java know how much (53) Use Java to create your own exception subclasses
Java know how much (54) assertion detailed
Java know how many (55) threads
Java know how much (56) threading ModelJava know how much (57) main threadJava know how much (58) thread Runnable interface and thread class explanationJava know how much (59) Create multithreadingJava know how much (isAlive) and join () useJava know how much (61) thread Priority
Java know how much (62) thread synchronization