The synchronized and the Lock thing.

Source: Internet
Author: User

Recently in a monitoring system, the system mainly includes real-time data analysis and storage of two parts, due to the high concurrency, so the inevitable use of some concurrency knowledge. To implement these requirements, the background uses a queue as the cache, and for the request, write the data to the cache. Simultaneously initiates a thread to listen to the queue, detects data, and immediately requests the dispatch thread to process the data. The specific use of the program is to use synchronization to ensure the normal data, using the thread pool to improve efficiency.

The implementation of synchronization is, of course, a lock, and the two basic tools for using locks in Java are synchronized and lock. Always like synchronized, because it is very convenient to use. For example, to synchronize a method, simply add a synchronized keyword to the signature of the method.     unsynchronized method public void Test () {}//synchronous method pubilc synchronized void Test () {} Synchronized can also be used on a block of code, see public void Test () {     Synchronized (obj) {System.out.println ("= = ="); }} Synchronized what is the difference between a method and a code block? Synchronized is used on the method signature (for example, test), and when a thread calls this method, it gets the object lock for that instance, and the other thread waits until the method ends. Object locks are released only when this method finishes executing. Other threads have the opportunity to seize the lock and execute the method test, but this should be based on the same object instance used by all the threads in order to achieve mutually exclusive behavior. Otherwise the Synchronized keyword will lose its meaning. ( However, if the method is a class method, that is, its modifier is static, then synchronized means that a thread that calls this method currently owns the lock of that class, as long as the thread continues to run within the current method, and other threads still cannot get the use of the method! Synchronized used in code blocks: synchronized (obj) {//todo code here} when a thread runs into that code block, it has an object lock on the Obj object, and if multiple threads share the same object, Then it will form mutual exclusion! In particular, when obj = = This represents an instance object that is currently calling the method. public void Test () {... synchronized (this) {//Todo Your code} ...} at this time, the effect is the same as public Synchron ized void Test () {///TODO Your code} uses synchronized blocks to synchronize only the code that needs to be synchronized, which can greatly improve efficiency. Summary: Using the synchronized code block compared to the method has two advantages: 1, can only be used in sync with 2, and Wait ()/notify ()/nitifyall () when used, it is more convenient--------------------------- --------------------------------------------------------------------------------------------------------------- ----------------Wait () with notify ()/notifyall () these three methods are the method of the object, not the threading Method! Wait (): Frees the owning object lock, the thread enters the waiting pool, frees the CPU, and the other waiting thread can preempt the lock, and the thread that obtains the lock can run the program. Unlike sleep (), when the thread calls this method, it sleeps for a period of time, temporarily releasing the CPU during hibernation, but does not release the object lock. That is, during hibernation, other threads still cannot get inside this code. The end of hibernation, the thread regain the CPU, execute the code. The biggest difference between wait () and sleep () is that wait () frees the object lock, and sleep () does not! Notify (): This method wakes up the thread that waits for the call to wait () of the object, which is actually Wake-up of an object lock so that the thread of Wait () has a chance to acquire an object lock。 After calling notify (), the lock is not released immediately, but the current code continues to execute until the code in the synchronized is fully executed before the object lock is released. The JVM will dispatch a thread in the waiting thread to get the object lock and execute the code. It is important to note that Wait () and notify () must be called in the synchronized code block。 Notifyall () is the wake-up of all waiting threads. To illustrate this, here are some examples: two threads print "A" "B" in turn, printing 10 times in total. Public classConsumer ImplementsRunnable {@Override Public synchronized voidRun () {// TODOauto-generated Method Stub intCount = 10; while(Count > 0) { synchronized(Test. obj) {System. out. Print ("B");                     Count--; Test. obj. Notify (); Actively releasing object locks Try{Test. obj. Wait (); } Catch(Interruptedexception e) {                            // TODOAuto-generated Catch block E.printstacktrace (); }                }                           }     }} Public classProduce ImplementsRunnable {@Override Public voidRun () {// TODOauto-generated Method Stub intCount = 10; while(Count > 0) { synchronized(Test. obj{//system.out.print ("Count =" + count); System. out. Print ("A");                     Count--; Test. obj. Notify (); Try{Test. obj. Wait (); } Catch(Interruptedexception e) {                            // TODOAuto-generated Catch block E.printstacktrace (); }}}} The test class is as follows: Public classTest { Public Static FinalObject obj= NewObject (); Public Static voidMain (string[] args) { NewThread ( NewProduce ()). Start (); NewThread ( NewConsumer ()). Start (); The static obj is used here as the object of the lock, and when the thread produce starts (if produce first obtains the lock, then consumer waits), after printing "A", the lock is released voluntarily and then blocks itself. Consumer get the object lock, print "B", then release the lock, block yourself, then produce will get the lock, then ... Keep looping until Count = 0. This allows thread synchronization to be achieved using synchronized and wait () and notify (). --------------------------------------------------------------------------------------------------------------- -------------------------------------------   In addition to the wait () and notify () collaboration to complete thread synchronization, using lock also accomplishes the same thing.  Reentrantlock and synchronized have the same concurrency and memory semantics, also include interrupt lock wait and timed lock wait, meaning that thread a if the object obj first obtained the lock, then thread B can wait for a specified period of time still cannot acquire the lock, then will automatically discard the lock. However, since synchronized is implemented at the JVM level, the system can monitor the release of the lock, and Reentrantlock uses the code to implement it, the system cannot automatically release the lock, and you need to explicitly release the lock Lock.unlock () in the finally clause in the code. For the same example, how does lock work? Public classConsumer ImplementsRunnable { PrivateLock lock; PublicConsumer (lock Lock) { This.     lock = lock; } @Override Public voidRun () {// TODOauto-generated Method Stub intCount = 10; while(Count > 0) { Try{Lock.lock ();                     Count--; System. out. Print ("B"); } finally{Lock.unlock ();//Active Release lock Try{Thread. Sleep(91L); } Catch(Interruptedexception e) {                            // TODOAuto-generated Catch block E.printstacktrace (); }                }           }      } } Public classProducer Implementsrunnable{ PrivateLock lock; PublicProducer (lock Lock) { This.     lock = lock; } @Override Public voidRun () {// TODOauto-generated Method Stub intCount = 10; while(Count > 0) { Try{Lock.lock ();                     Count--; System. out. Print ("A"); } finally{Lock.unlock (); Try{Thread. Sleep(90L); } Catch(Interruptedexception e) {                            // TODOAuto-generated Catch block E.printstacktrace (); }}}} call code: Public classTest { Public Static voidMain (string[] args) {Lock lock = NewReentrantlock (); Consumer Consumer = NewConsumer (lock); Producer Producer = NewProducer (lock); NewThread (consumer). Start (); NewThread (producer). Start (); }}: Using synchronized is a good choice when the concurrency ratio is small, but with a high concurrency rate, the performance degradation is severe, and reentrantlock is a good solution at this point.

The synchronized and the Lock thing.

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.