Java-efficient timing Task Design, Java-Task Design

Source: Internet
Author: User

Java-efficient timing Task Design, Java-Task Design

I believe you must have encountered this problem in daily development: You need to manage the state information of the entity class, for example, changing it to the XXX state after a certain period of time.

For example, in order service, if the user does not pay the order within 30 minutes after submitting the order, the order is automatically canceled, which is a management of the status;

Another example of my actual development is the message pipeline. After a user pulls a message, if the message is not submitted within 30 s, his subscription status is changed to unsubscribed, in this way, other instances can establish connections to continue reading.

Organize the design drawing:

The core is: a Thread + a Queue; the Thread constantly extracts data from the Queue. If the Queue is empty or the task in the Queue does not expire, the Thread gets stuck with wait (timeOut ).

Ii. Detailed Design

First, a simple stateful entity class: ConsumerInfoState. The core of this class is the status (subscription expiration time), so you have to set the status query, query how long it will take to expire ....

Import java. io. serializable; public class ConsumerInfoState implements Serializable {/*** serialization ID */private static final long serialVersionUID = 1L;/*** expiration time 20 s */protected long expiration; private String topic; private String userId; private boolean isSubscribed = false; private long CONSUMER_INSTANCE_TIMEOUT_MS_DEFAULT = 5000; public ConsumerInfoState (String userId) {this. userId = userId; this. expiration = System. currentTimeMillis () + CONSUMER_INSTANCE_TIMEOUT_MS_DEFAULT;} public ConsumerInfoState (String topic, String userId) {super (); this. topic = topic; this. userId = userId; this. expiration = System. currentTimeMillis () + CONSUMER_INSTANCE_TIMEOUT_MS_DEFAULT;}/*** expired? */public boolean expired (long nowMs) {return expiration <= nowMs ;} /*** <p> * Update Subscription expiration time * </p> */public void updateExpiration () {this. expiration = System. currentTimeMillis () + CONSUMER_INSTANCE_TIMEOUT_MS_DEFAULT;}/*** <p> * How long will it take to reach the specified time * </p> */public long untilExpiration (long nowMs) {return this. expiration-nowMs;} public String getUserId () {return userId;} public String getTopic () {return topic;} public void setTopic (String topic) {this. topic = topic;} public void setSubscribed (boolean isSubscribed) {this. isSubscribed = isSubscribed;} public boolean hasSubscribed () {return isSubscribed ;}}

This class is still very clear ..

Core class: ConsumerInfoManager

Import java. util. comparator; import java. util. priorityQueue; import java. util. concurrent. countDownLatch; import java. util. concurrent. atomic. atomicBoolean; import org. slf4j. logger; import org. slf4j. loggerFactory; public class ConsumerInfoManager {Logger logger = LoggerFactory. getLogger (ConsumerInfoManager. class); // task queue private final PriorityQueue <ConsumerInfoState> consumersByExpiration = new PriorityQu Eue <ConsumerInfoState> (new Comparator <ConsumerInfoState> () {// small front public int compare (ConsumerInfoState o1, ConsumerInfoState o2) {if (o1.expiration <o2.expiration) {return-1;} else if (o1.expiration = o2.expiration) {return 0;} else {return 1 ;}}); private ExpirationThread expirationThread; public ConsumerInfoManager () {// start thread this. expirationThread = new ExpirationThread (); this. expir AtionThread. start () ;}// add to the task queue public synchronized void addConsumerInfoSate (ConsumerInfoState consumerInfoSate) {consumersByExpiration. add (consumerInfoSate); this. notifyAll () ;}@ SuppressWarnings ("unused") public synchronized void updateExpiration (ConsumerInfoState state) {// delete it in the put directory and re-Sort consumersByExpiration. remove (state); state. updateExpiration (); consumersByExpiration. add (state); this. notif YAll ();} public void shutdown () {logger. debug ("Shutting down consumers"); expirationThread. shutdown (); synchronized (this) {consumersByExpiration. clear () ;}/ ***** <p> * Check the consumerInfo expiration time, delete expired files from the cache * </p> * @ author jiangyuechao January 13, 2018 2:04:30 */@ SuppressWarnings ("unused ") private class ExpirationThread extends Thread {AtomicBoolean isRunning = new AtomicBoolean (true); CountDownLatch ShutdownLatch = new CountDownLatch (1); public ExpirationThread () {super ("Consumer Expiration Thread"); setDaemon (true) ;}@ Override public void run () {synchronized (ConsumerInfoManager. this) {try {while (isRunning. get () {long now = System. currentTimeMillis (); // determines whether the queue is empty and whether the last task expires (! ConsumersByExpiration. isEmpty () & consumersByExpiration. peek (). expired (now) {final ConsumerInfoState state = consumersByExpiration. remove (); // {Your Own Business Processing} state. setSubscribed (false); logger.info ("the task has expired, topic :{}, userID :{}, subscribed :{}", state. getTopic (), state. getUserId (), state. hasSubscribed ();} // long timeout = consumersByExpiration. isEmpty ()? Long. MAX_VALUE: consumersByExpiration. peek (). untilExpiration (now); ConsumerInfoManager. this. wait (timeout) ;}} catch (InterruptedException e) {// Interrupted by other thread, do nothing to allow this thread to exit logger. error ("ExpirationThread thread interruption", e) ;}} shutdownLatch. countDown ();} public void shutdown () {try {isRunning. set (false); this. interrupt (); shutdownLatch. await ();} catch (InterruptedException e) {throw new Error ("Interrupted when shutting down consumer worker thread. ") ;}} public void join () {try {expirationThread. join ();} catch (InterruptedException e) {// TODO Auto-generated catch blocke. printStackTrace ();}}}

I deleted the code and deleted the unimportant part. In general, ConsumerInfoManager also needs a Cache, which is used to store all entity classes, and the queue is part of the Cache, generally, when a task in the queue expires, You need to delete or retrieve it from the Cache to perform some operations.

Of course, adding Cache is complicated. The core idea is that additional code is deleted ..

Test
Public class ManagerTest {static ConsumerInfoManager consumerInfoManager; static String userId = "dhsajkdsajkdsjh1"; static Logger logger = LoggerFactory. getLogger (ManagerTest. class); public static void main (String [] args) throws InterruptedException {// instantiate setUp (); for (int I = 0; I <3; I ++) {ConsumerInfoState consumerInfoState = new ConsumerInfoState ("chao-" + I, userId); consumerInfoState. setSubscribed (true); consumerInfoManager. addConsumerInfoSate (consumerInfoState); logger.info ("task" + I + "add to queue"); Thread. sleep (1000);} consumerInfoManager. join () ;}public static void setUp () {consumerInfoManager = new ConsumerInfoManager ();}}

Output result: as expected...

10:07:27, 450 [main] INFO ManagerTest-task 0 joins the queue
10:07:28, 451 [main] INFO ManagerTest-Task 1 joined the queue
10:07:29, 451 [main] INFO ManagerTest-Task 2 joined the queue
10:07:32, 451 [Consumer Expiration Thread] INFO ConsumerInfoManager-task expired, topic: chao-0, userID: dhsajkdsajkdsjh1, subscribed: false
10:07:33, 485 [Consumer Expiration Thread] INFO ConsumerInfoManager-task expired, topic: chao-1, userID: dhsajkdsajkdsjh1, subscribed: false
10:07:34, 452 [Consumer Expiration Thread] INFO ConsumerInfoManager-task expired, topic: chao-2, userID: dhsajkdsajkdsjh1, subscribed: false

Please indicate the source of forwarding: http://www.cnblogs.com/jycboy/p/8301538.html

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.