Building a custom synchronization tool in Java concurrent programming _java

Source: Internet
Author: User
Tags throw exception

When the Java class Library does not provide the appropriate synchronization tools, you need to build a custom synchronization tool.

Structures that can block state-dependent operations

Copy Code code as follows:

Acquir lock on object state;//request acquire lock
While (precondition does not hold) {//No prerequisites are met
Release lock;//unlock First
Wait until precondition might hold;//waiting to meet the prerequisites
Optionlly fail if interrupted or timeout expires;//due to interruption or timeout execution failed
Reacquire lock;//try to acquire the lock again
}
Perform action//execution
Release lock;//unlock

Example of a base class with bounded cache implementations

Copy Code code as follows:

public class Baseboundbuffer<v> {
Private final v[] buf;
private int tail;
private int head;
private int count;
@SuppressWarnings ("Unchecked")
public baseboundbuffer (int capacity) {
BUF = (v[]) new object[capacity];
}
Public synchronized void DoPut (v V) {
Buf[tail] = v;
if (++tail = = buf.length)
tail = 0;
count++;
}
Public synchronized V Dotake () {
V v = buf[head];

if (++head = = buf.length)
Head = 0;
count--;
return v;
}
Public final Synchronized Boolean isfull () {
return count = = Buf.length;
}
Public final Synchronized Boolean IsEmpty () {
return count = = 0;
}
}

Blocking implementation method One: Throw exception to caller

Copy Code code as follows:

Public synchronized void Put1 (v V) throws exception{
if (Isfull ())
throw new Exception ("full error");
DoPut (v);
}

Analysis: Exceptions should be applied in the event of an exception, where it is inappropriate to throw an exception, and the need for the caller to handle a prerequisite failure and not solve the underlying problem.
blocking implementation Two: polling and hibernation
Copy Code code as follows:

public void Put2 (v V) throws Interruptedexception {
while (true) {//polling
Synchronized (this) {
if (!isfull ()) {
DoPut (v);
Return
}
}
Thread.Sleep (sleep_time);//Hibernate
}
}

Analysis: It is difficult to weigh the sleep time sleep_time settings. If the settings are too small, the CPU may poll multiple times and the CPU resources are higher, and if the settings are too large, the lower the responsiveness.

Blocking implementation mode three: conditional queues

The elements in the conditional queue are threads that wait for the relevant criteria. Each Java object can be used as a lock, and each object can also serve as a conditional queue, and the wait, notify, Notifyall methods in object form an API for the internal condition queue. Object.wait automatically releases the lock and requests the operating system to suspend the current thread so that other threads can acquire the lock and modify the object's state. Object.notify and Object.notifyall can wake up the waiting thread, pick a thread from the criteria queue to wake and try to regain the lock.

Copy Code code as follows:

Public synchronized void Put3 (v V) throws Interruptedexception {
while (Isfull ())
Wait ();
Doput (v);
Notifyall ();
}

Analysis: Get better response, easy to use.

Working with conditional queues
1. Conditional predicates

1). Definition: A conditional predicate is a prerequisite for making an operation a state dependent operation. A conditional predicate is an expression that consists of individual state variables in a class. For example, the conditional predicate for the Put method is "cache is not empty."
2. Relationship: There is an important ternary relation in conditional waiting, including lock, wait method and a conditional predicate. There are multiple state variables in the conditional predicate, and each state variable must be protected by a lock, so you must first hold the lock before testing the conditional verb. Lock objects and Conditional queue objects (and objects that invoke methods such as wait and notify) must be the same object.
3. Constraint: Each call to wait is implicitly associated with a particular conditional predicate, and when a particular conditional predicate is invoked, the caller must already hold the lock associated with the conditional queue, which must also protect the state variables of the constituent condition predicate

2. Conditional Queue Usage Rules

1). There is usually a conditional predicate
2. Always test the conditional predicate before calling wait, and then test again after returning in wait;
3. Always call wait in the loop;
4. Ensure that the state variable that constitutes the conditional predicate is protected by the lock, which must be associated with the conditional queue;
5. When calling wait, notify and Notifyall, hold the lock associated with the conditional queue;
6. Do not release the lock until the conditional verb is checked, before starting to execute the protected logic;

3. Notice

Try to use Notifyall instead of nofify. Because Nofify will randomly wake a thread from hibernation to blocked state (the blocked state is a state in which a thread is always trying to acquire a lock, that is, once the lock is found to be available, the lock is immediately held). Notifyall wakes all threads in the conditional queue from hibernation to blocked state. In this case, if thread A is dormant because of the conditional verb PA, thread B is in hibernation because of the conditional predicate PB. Then PB is True, Thread C executes a single notify. If the JVM randomly chooses thread A to wake, thread a checks the condition predicate that the PA is not true and then enters hibernation. No other thread has been awakened since then, and the program is dormant. If you use Notifyall, The JVM wakes up all waiting threads in the conditional queue from hibernation to blocked state, even if a random thread is selected because the conditional predicate does not actually enter hibernation, other threads will also compete for the lock and continue to execute.

4. Standard form of state-dependent methods

Copy Code code as follows:

void Statedependentmethod throwsinterruptedexception{
Synchronized (lock) {
while (!conditionpredicate))
Lock.wait ();
}
DoSomething ();
....

Notifyall ();
}

Show Condition objects

The condition object shown is a more flexible choice that provides richer functionality: there can be multiple waits on each lock, conditional waiting can be interrupted by interruptible, time-based wait, and fair or unfair queue operations. A condition can be associated with a lock, just as a conditional queue is associated with a built-in lock. To create a condition, you can increase the Lock.newcondition method on the associated lock. The following uses display condition variables to implement the bounded cache again

Copy Code code as follows:

public class Conditionboundedbuffer<v> {
Private final v[] buf;
private int tail;
private int head;
private int count;
Private lock lock = new Reentrantlock ();
Private Condition notfullcondition = Lock.newcondition ();
Private Condition notemptycondition = Lock.newcondition ();
@SuppressWarnings ("Unchecked")
public conditionboundedbuffer (int capacity) {
BUF = (v[]) new object[capacity];
}

public void DoPut (v V) throws Interruptedexception {
try {
Lock.lock ();
while (count = = buf.length)
Notfullcondition.await ();
Buf[tail] = v;
if (++tail = = buf.length)
tail = 0;
count++;
Notemptycondition.signal ();
finally {
Lock.unlock ();
}

}

Public V Dotake () throws Interruptedexception {
try {
Lock.lock ();
while (count = = 0)
Notemptycondition.await ();
V v = buf[head];
Buf[head] = null;
if (++head = = buf.length)
Head = 0;
count--;
Notfullcondition.signal ();
return v;
finally {
Lock.unlock ();
}
}
}

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.