Multithreaded programming-design mode protective hold (guarded suspesion) mode

Source: Internet
Author: User

Guarded schema for suspension mode

The


Core is a protected method (guarded). The method needs to perform the operation it wants to perform exactly when it needs to meet a specific condition (predicate, hereinafter referred to as a protection condition). When the condition is not met, the thread that executes the protected method is suspended into a wait state until the thread continues to run until the condition is satisfied. At this point, the protected method is performing the action it is performing (the target operation).
Guardedobject: The object that contains the protected method. The main methods and responsibilities are as follows:
-guardedmethod: Protected method.
-statechanged: The method that alters the state of the Guardedobject instance, which is responsible for waking the executing thread of the protected method when the protection condition is established.
Guardedaction: Abstracts the target action and associates the protection conditions required for the target action. The main methods are
-call: The method used to represent the target action.
Concreteguardedaction: The specific target action implemented by the application and its associated protection conditions.
Predicate: Abstract protection condition
-evaluate: The method used to represent the protection condition.
Concretepredicate: The specific protection conditions implemented by the application.
Blocker: is responsible for suspending and waking the thread that executes the Guardedmethod method and performing the target operation that the concreteguardedaction implements. The main methods are as follows:
Callwithguarded: Responsible for performing the target operation and suspending the current thread.
Singleafter: A thread in the thread that is responsible for executing the action specified by its arguments and the wake-up method to which the blocker instance is suspended.
Signal: is responsible for waking a thread in a thread that is suspended by the blocker instance to which the method belongs.
Broadcastafter: is responsible for executing the actions specified by its arguments and waking up all threads that are suspended by the blocker instance to which the method belongs.
Broadcast: is responsible for waking up all threads that are suspended by the blocker instance to which the method belongs.
Conditionvarblocker: Blocker based on the Java condition variable condition implementation.



Call Procedure:
1.client calls the protected method Guardedmethod.
The 2.guardedMethod method creates the Guardedaction instance guardedaction.
The 3.guardedMethod method invokes the Callwithguarded method of the blocker instance with guardedaction as a parameter.
The 4-5:callwithguarded method calls the Guardedaction getguarded method to get the protection condition predicate.
6-8 These steps are a loop. The loop determines whether the daemon is valid. If the protection condition is true, the loop exits. Otherwise, the loop suspends the current thread and puts it in a wait state. When another thread wakes up the suspended thread, the loop continues to monitor the protection condition and repeats the above logic.
The 9-10:callwithguarded method invokes the call method of Guardedaction to perform the target operation and records the return value of the calling method Actionreturnvalue.
The 11.callWithGuarded method returns the Actionreturnvalue as its return value to the caller.
The 12.guaredMethod method returns.

Case Study: System Alarm function module
The main function is to send the alarm information it receives to the alarm server. The class alarmagent is responsible for interfacing with the alarm server. The Sendalarm method is responsible for sending the alarm information to the alarm server over a network connection. Alarmagent creates a dedicated thread for it to establish a network connection with the alarm server. Therefore, when the Sendalarm method is called, the connection thread may not have completed establishing the network connection. At this point, the Snedalarm method should wait for the connection thread to establish a good network connection. In addition, even if the connection thread establishes a network connection, it may be possible to disconnect the alarm server for some reason. At this point, the Sendalarm method needs to wait for the heartbeat task to reestablish the connection before reporting the police information. In other words, the Snedalarm method must perform the required operation if the network connection between the alarmagent and the alarm server is established successfully. If the alarmagent connection to the alarm server is not established (or if the connection is interrupted), the execution thread of the Sendalarm method should be suspended until the connection is established (or resumed).

The above problems can be solved by guarded suspension mode.
Import lombok.extern.slf4j.Slf4j;
Import Java.util.Timer;
Import Java.util.TimerTask;
Import java.util.concurrent.Callable;
/**
* Responsible for connecting the alarm server and sending alarm information to the alarm server
*
*/
@Slf4j
public class Alarmagent {
Used to record whether the alarmagent is connected to appeal police server
Private volatile Boolean connectedtoserver = false;
public static void Main (string[] args) {
Alarmagent alarmagent = new Alarmagent ();
Alarmagent.init ();
}
Mode role: Guardedsuspension.predicate
Private final predicate agentconnected = new predicate () {
@Override
public Boolean evaluate () {
return connectedtoserver;
}
};
Mode role: Guardedsuspension.blocker
Private final blocker blocker = new Conditionvarblocker ();
Heartbeat Timer
Private final Timer Heartbeattimer = new timer (true);
Omit other code
/**
* Send Alarm message
* @param alarm Alarm Information
* @throws Exception
*/
public void Sendalarm (final alarminfo alarm) throws Exception {
You may need to wait until Alarmagent connects to the appeal server (or the server restarts after the connection is interrupted)
Mode role: Guardedsuspension.guardedaction
guardedaction<void> guardedaction = new Guardedaction<void> (agentconnected) {
Public Void Call () throws Exception {
Dosendalarm (alarm);
return null;
}
};
Blocker.callwithguard (guardedaction);
}
Sending alarm information to an alarm server over a network connection
private void Dosendalarm (Alarminfo alarm) {
Omit other code
Log.info ("Sending alarm" + alarm);
Simulate the time-consuming of sending alarms to the server
try {
Thread.Sleep (50);
} catch (Exception e) {
}
}
public void init () {
Omit other code
Alarm connection Thread
Thread connectingthread = new Thread (new Connectingtask ());
Connectingthread.start ();
Heartbeattimer.schedule (New Heartbeattask (), 60000, 2000);
}
public void Disconnect () {
Omit other code
Log.info ("Disconnected from alarm server.");
Connectedtoserver = false;
}
protected void onconnected () {
try {
Blocker.signalafter (New callable<boolean> () {
@Override
Public Boolean call () {
Connectedtoserver = true;
Log.info ("connected to server");
return boolean.true;
}
});
} catch (Exception e) {
E.printstacktrace ();
}
}
protected void ondisconnected () {
Connectedtoserver = false;
}
Responsible for establishing network connection with alarm server
Private class Connectingtask implements Runnable {
@Override
public void Run () {
Omit other code
Time-consuming analog connection operation
try {
Thread.Sleep (100);
} catch (Interruptedexception e) {
;
}
Onconnected ();
}
}
/**
* Heartbeat Timer Task: Check the connection with the alarm server correctly, and automatically reconnect after the connection exception is found
*/
Private class Heartbeattask extends TimerTask {
Omit other code
@Override
public void Run () {
Omit other code
if (!testconnection ()) {
Ondisconnected ();
Reconnect ();
}
}
Private Boolean testconnection () {
Omit other code
return true;
}
private void Reconnect () {
Connectingtask connectingthread = new Connectingtask ();
Executes directly in the heartbeat timer thread
Connectingthread.run ();
}
}
}
Blocker interface:
Import java.util.concurrent.Callable;

/**
* @author
* @create 2017-09-30 1:15
*/
public interface Blocker {
/**
* Execute the target action when the protection condition is established, otherwise block the current thread until the protection condition is established.
* @param guardedaction target action with protective conditions
* @return
* @throws Exception
*/
<V> V Callwithguard (guardedaction<v> guardedaction) throws Exception;
/**
* After performing the operation specified by Stateoperation, decide whether to wake the blocker
* One thread in all the threads that are suspended.
*
* @param stateoperation
* When you change the state of an operation whose call method's return value is true, the method wakes the suspended thread
*/
void Signalafter (Callable<boolean> stateoperation) throws Exception;

void signal () throws interruptedexception;

/**
* After performing the operation specified by Stateoperation, decide whether to wake the blocker
* All threads that are suspended.
*
* @param stateoperation
* When you change the state of an operation whose call method's return value is true, the method wakes the suspended thread
*/
void Broadcastafter (Callable<boolean> stateoperation) throws Exception;
}

Conditionvarblocker
Import lombok.extern.slf4j.Slf4j;

Import java.util.concurrent.Callable;
Import java.util.concurrent.locks.Condition;
Import Java.util.concurrent.locks.Lock;
Import Java.util.concurrent.locks.ReentrantLock;

/**
* @author
* @create 2017-09-30 1:18
*/
@Slf4j
public class Conditionvarblocker implements blocker {
Private final lock lock;

Private final Condition Condition;

Private Final Boolean allowaccess2lock;

Public Conditionvarblocker (lock Lock) {
This (lock, true);
}

Private Conditionvarblocker (Lock Lock, Boolean Allowaccess2lock) {
This.lock = lock;
This.allowaccess2lock = Allowaccess2lock;
This.condition = Lock.newcondition ();
}

Public Conditionvarblocker () {
This (false);
}

Public Conditionvarblocker (Boolean allowaccess2lock) {
This (new Reentrantlock (), allowaccess2lock);
}

Public Lock Getlock () {
if (Allowaccess2lock) {
return this.lock;
}
throw new IllegalStateException ("Access to the lock disallowed.");
}

Public <V> V Callwithguard (guardedaction<v> guardedaction) throws Exception {
Get lock
Lock.lockinterruptibly ();
V result;
try {
Critical section Code
Obtaining protection conditions
Final predicate guard = Guardedaction.guard;
while (!guard.evaluate ()) {
Protection conditions are not established threads suspend suspended Conditionvarblocker instances
Log.info ("Waiting ...");
Condition.await ();
}
Perform target actions
result = Guardedaction.call ();
return result;
} finally {
Release lock ensures that the lock is always released.
Lock.unlock ();
}
}

public void Signalafter (Callable<boolean> stateoperation) throws Exception {
Lock.lockinterruptibly ();
try {
if (Stateoperation.call ()) {
Condition.signal ();
}
} finally {
Lock.unlock ();
}

}

public void Broadcastafter (Callable<boolean> stateoperation) throws Exception {
Lock.lockinterruptibly ();
try {
if (Stateoperation.call ()) {
Condition.signalall ();
}
} finally {
Lock.unlock ();
}

}

public void signal () throws Interruptedexception {
Lock.lockinterruptibly ();
try {
Condition.signal ();

} finally {
Lock.unlock ();
}

}
}
Package Com.credithc.finance.com.design.guardedmethod;

Import java.util.concurrent.Callable;

/**
* @author
* @create 2017-09-30 1:16
*/

Public abstract class Guardedaction <v>implements callable<v> {


Protected final predicate guard;

Public guardedaction (predicate guard) {
This.guard = Guard;
}
}
Package Com.credithc.finance.com.design.guardedmethod;

/**
* Protection Condition judgment
*
* @author
* @create 2017-09-30 1:17
*/
public interface Predicate {
Boolean evaluate ();
}
Thread Timer-0 waits for the Lock (Helper) held by the thread Thread-0 and the helper held by the thread Thread-0 has not been released
Reusable code: Predicate,guardedaction,blocker,conditionvarblocker
Code that needs to be implemented by itself: Guaredobject concretepredicate concreteguardedaction Several participant instances

Issues to be concerned with

Memory visibility and lock leaks
Thread is awakened prematurely
Nested monitors lock dead
May increase the burden of JVM garbage collection

RELATED Links: http://blog.csdn.net/huzhiqiangCSDN/article/details/55045110

Multithreaded programming-design mode protective hold (guarded suspesion) mode

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.