28. Java Concurrency and multithreading-profiling synchronizer

Source: Internet
Author: User

The following is transferred from http://ifeve.com/anatomy-of-a-synchronizer/:

Although many synchronizers (such as locks, semaphores, blocking queues, etc.) function differently, their internal design is very different. In other words, the underlying parts of their internals are identical (or similar). Understanding these basic components can help us greatly when designing Synchronizer. This is what this article is going to elaborate.

Note: The content of this article is the Bjørn of the University of Information technology in Copenhagen, which was attended by Jakob Jenkov,toke Johansen and Lars M.Sc. part of the results of the student program. During this project we consulted Doug Lea whether they knew similar studies. Interestingly, he has come up with a similar conclusion during the development of the Java 5 Concurrency Toolkit. Doug Lea's research, I believe, is described in the book "Java Concurrency in Practice". This book has a chapter "anatomy Synchronizer" similar to this article, but not the same.

Most synchronizers are code that protects a zone (a critical section) that may be accessed concurrently by multiple threads. To achieve this goal, the Synchronizer generally supports the following functions:

    1. State
    2. Access conditions
    3. State change
    4. Notification policy
    5. Test-and-set method
    6. Set method

Not all synchronizers contain the above-mentioned parts, and some do not fully comply with the above content. But usually you can find one or more of these parts from it.

State

The state in the Synchronizer is used to determine whether a thread has access rights. In lock, the state is of type Boolean, indicating whether the current lock object is in a locked state. In Boundedsemaphore, the internal state contains a counter (type int) and an upper bound (int type) that represents the number of licenses currently acquired and the maximum number of licenses available. The status of Blockingqueue is the list of elements in the queue and the maximum capacity of the queue.

Here are the two code snippets in lock and Boundedsemaphore.

 Public classlock{//State was kept here  Private BooleanisLocked =false;  Public synchronized voidLock ()throwsinterruptedexception{ while(isLocked) {wait (); } isLocked=true; }  ...} Public classBoundedsemaphore {//State was kept here      Private intSignals = 0; Private intBound = 0;  PublicBoundedsemaphore (intupperbound) {     This. Bound =Upperbound; }   Public synchronized voidTake ()throwsinterruptedexception{ while( This. Signals = =bound) wait ();  This. signal++;  This. Notify (); }  ...}

Access conditions

The access condition determines whether the thread that invokes the Test-and-set-state method can set the state. Access conditions are generally based on the state of the Synchronizer. is usually placed in a while loop to avoid false wakeup problems. The evaluation of the access condition is either true or false.

The access condition in lock simply checks the value of the islocked. Depending on whether the action performed is get or release, there are actually two access conditions in Boundedsemaphore. If a thread wants to "get" the license, it checks whether the signals variable is capped, and if a thread wants to "release" the license, it checks whether the signals variable is 0.

There are two code snippets from lock and Boundedsemaphore, all of which have access conditions. Notice how the observation condition is checked in the while loop.

 Public classlock{Private BooleanisLocked =false;  Public synchronized voidLock ()throwsinterruptedexception{//Access Condition     while(isLocked) {wait (); } isLocked=true; }  ...} Public classBoundedsemaphore {Private intSignals = 0; Private intBound = 0;  PublicBoundedsemaphore (intupperbound) {     This. Bound =Upperbound; }   Public synchronized voidTake ()throwsinterruptedexception{//Access Condition     while( This. Signals = =bound) wait ();  This. signals++;  This. Notify (); }   Public synchronized voidRelease ()throwsinterruptedexception{//Access Condition     while( This. Signals = = 0) wait ();  This. signals--;  This. Notify (); }}

State change

Once a thread has access to a critical section, it has to change the state of the Synchronizer, blocking other threads and preventing them from entering the critical section. In other words, this state indicates that a thread is executing a critical section of code. When other threads want to access the critical section, the state should affect the result of the access condition.

In lock, the code is set islocked = True to change the state, in the semaphore, change the state is signals– or signals++;

Here are two code snippets of state change:

 Public classlock{Private BooleanisLocked =false;  Public synchronized voidLock ()throwsinterruptedexception{ while(isLocked) {wait (); }    // State ChangeisLocked =true; }   Public synchronized voidunlock () {// State ChangeisLocked =false;  Notify (); }} Public classBoundedsemaphore {Private intSignals = 0; Private intBound = 0;  PublicBoundedsemaphore (intupperbound) {     This. Bound =Upperbound; }   Public synchronized voidTake ()throwsinterruptedexception{ while( This. Signals = =bound) wait (); // State Change     This. signals++;  This. Notify (); }   Public synchronized voidRelease ()throwsinterruptedexception{ while( This. Signals = = 0) wait (); // State Change     This. signals--;  This. Notify (); }}

Notification policy

Once a thread has changed the state of the Synchronizer, it may be necessary to notify other waiting threads that the state has changed. Because perhaps the change in this state will make the access conditions of other threads true.

Notification policies are typically divided into three types:

    1. Notifies all waiting threads
    2. Notifies N of any one of the waiting threads
    3. Notifies N of a specified thread in a waiting thread

It is very easy to notify all waiting threads. All waiting threads call the Wait () method on the same object, and a thread wants to notify them simply to call the Notifyall () method on the object.

It is also easy to notify any of the waiting threads, just change the Notifyall () call to notify (). Calling the Notify method has no way of determining which thread is waking, that is, "any of the waiting threads."

Sometimes it may be necessary to notify the specified thread rather than any waiting thread. For example, if you want to ensure that threads are notified in the same order that they enter the synchronization block, or in a priority order. To implement this requirement, each waiting thread must call Wait () on its own object. The Notify () method of invoking the thread's own object is called when the notification thread wants to notify a particular waiting thread. There are examples of hunger and equity.

The following is an example of a notification policy (notifies any waiting thread):

 Public classlock{Private BooleanisLocked =false;  Public synchronized voidLock ()throwsinterruptedexception{ while(isLocked) {//wait strategy-related to notification strategywait (); } isLocked=true; }   Public synchronized voidunlock () {isLocked=false; Notify (); //Notification Strategy  }}

Test-and-set method

There are two types of methods that are most common in a Synchronizer, Test-and-set is the first (set is another). Test-and-set means that the thread that calls this method checks the access condition and, if satisfied, sets the internal state of the Synchronizer to indicate that it has been granted access.

A change in state usually results in a false result when other threads trying to gain access are evaluated for the condition state, but not necessarily always. For example, in a read-write lock, the thread that acquires the read lock updates the state of the read-write lock to indicate that it acquires a read lock, but the other thread that requests the read lock succeeds as long as no thread requests a write lock.

Test-and-set is necessary to be atomic, which means that no other thread is allowed to execute in the Test-and-set method while a thread is checking and setting the state.

The program flow of the Test-and-set method is often followed in the following order:

    1. If necessary, set the status before checking
    2. Check Access criteria
    3. If the access condition is not met, wait for the
    4. If access conditions are met, set the state, and notify the waiting thread if necessary

The Lockwrite () method of the Readwritelock class below shows the Test-and-set method. The thread calling Lockwrite () sets the state (writerequests++) before checking. Then check the access conditions in cangrantwriteaccess (), and if the check passes, set the internal state again before exiting the method. There is no way to notify the waiting thread in this method.

 Public classreadwritelock{PrivateMap<thread, integer> readingthreads =NewHashmap<thread, integer>(); Private intwriteaccesses = 0; Private intwriterequests = 0; PrivateThread Writingthread =NULL; ...             Public synchronized voidLockwrite ()throwsinterruptedexception{writerequests++; Thread Callingthread=Thread.CurrentThread ();  while(!cangrantwriteaccess (Callingthread))        {Wait (); } writerequests--; Writeaccesses++; Writingthread=Callingthread; }        ...}

The following Boundedsemaphore class has two Test-and-set methods: Take () and release (). Two methods have check and set internal state.

 Public classBoundedsemaphore {Private intSignals = 0; Private intBound = 0;  PublicBoundedsemaphore (intupperbound) {     This. Bound =Upperbound; }         Public synchronized voidTake ()throwsinterruptedexception{ while( This. Signals = =bound) wait ();  This. signals++;  This. Notify (); }       Public synchronized voidRelease ()throwsinterruptedexception{ while( This. Signals = = 0) wait ();  This. signals--;  This. Notify (); }  }

Set method

The Set method is the second method common in the Synchronizer. The Set method only sets the internal state of the Synchronizer without first checking. A typical example of the Set method is the Unlock () method in the lock class. A thread holding a lock is always able to unlock successfully without checking that the lock is in an unlocked state.

The program flow of the set method is usually as follows:

    1. Set internal state
    2. Notifies the waiting thread

Here is an example of the Unlock () method:

 Public class lock{  Privatebooleanfalse;          Public synchronized void unlock () {      false;      Notify ();      }  }

28. Java Concurrency and multithreading-profiling synchronizer

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.