多线程设计模式-半同步/半异步模式

定义: 一个分层架构,将系统中的任务进行恰当地分解,使各个子任务落入合适的层次中

半同步/半异步模式UML图

AsyncTask: 异步任务,负责接收来自客户端的输入,对其进行初步处理,并通过队列与相应的同步任务通信
    dispatch: 对输入进行初步处理,并构造相应消息放入队列由相应的同步任务进行处理
Queue: 队列,异步任务层和同步任务层进行通信的中介
    enqueue: 消息入队列
    dequeue: 消息出队列
SyncTask: 同步任务,负责处理队列中的消息所对应的计算
    run: 执行同步任务

由于此处设计到部分其它模式使用的代码,就不一一贴出来了,具体可以从我的Github上查阅。

有时候,一些网络IO操作比较慢,做异步处理,一些处理相对来说较块,例如计数之类的,这种一般为同步模式。通过半同步/半异步的方式让两个处理速度不一致的任务互不影响。

package com.bruce.halfSyncHalfAsync;

import com.bruce.guardedSuspension.AlarmType;
import com.bruce.twoPhaseTermination.AlarmMgr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;

/**
* @Author: Bruce
* @Date: 2019/6/6 16:22
* @Version 1.0
*/
public class SampleAlarmClient {

    private final static Logger LOG = LoggerFactory.getLogger(SampleAlarmClient.class);

    private static final int ALARM_MSG_SUPRESS_THRESHOLD = 10;

    static {
        AlarmMgr.getInstance().init();
    }

    public static void main(String[] args) {
        SampleAlarmClient alarmClient = new SampleAlarmClient();
        Connection dbConn = null;
        try {
            dbConn = alarmClient.retrieveDBConnection();
        } catch (Exception e) {
            final AlarmMgr alarmMgr = AlarmMgr.getInstance();

            int duplicateSubmissionCount;
            String alarmId = "00000010000020";
            final String alarmExtraInfo = "operation=GetDBConnection;detail=Failed to get DB connection:"
                    + e.getMessage();

            duplicateSubmissionCount = alarmMgr.sendAlarm(AlarmType.FAULT, alarmId, alarmExtraInfo);
            if (duplicateSubmissionCount < ALARM_MSG_SUPRESS_THRESHOLD) {
                LOG.error("Alarm[" + alarmId + "] raised, extraInfo:" + alarmExtraInfo);
            } else {
                if (duplicateSubmissionCount == ALARM_MSG_SUPRESS_THRESHOLD) {
                    LOG.error("Alarm[" + alarmId + "] was raised more than " + ALARM_MSG_SUPRESS_THRESHOLD
                    + " times, it will no longer be logged.");
                }
            }
            return;

        }
        alarmClient.doSomething(dbConn);
    }

    private Connection retrieveDBConnection() throws Exception {
        Connection cnn = null;

        return cnn;
    }

    private void doSomething(Connection cnn) {
    }

}


半同步/半异步的优点:
增加系统的并发性,减少等待,保持同步编程的简单性。, 通常将耗时较短任务放在异步层,减少客户端的等待,提升系统吞吐率。,耗时较长任务放在同步层。
使用该模式需要根据实际情况选择有界队列和无界队列,有界队列可以在队列满的情况下,降低生产者的处理速率,减轻消费者的处理负担

参考资料

黄文海 Java多线程编程实战指南(设计模式篇)

黄文海的Github

猜你喜欢

转载自blog.csdn.net/u010145219/article/details/91349042