JAVA同步转异步

来源:互联网 发布:nao机器人编程 编辑:程序博客网 时间:2024/06/05 02:18



客户端使用,代码清洁,装饰器模式

 

public class JobHandlerAsyncDemo {    public static class JobHandlerDirect implements IJobHandler<String> {        @Override        public void doJob(String job) {            System.out.println("do job ..."+job);        }    }    public static void main(String[] args) {        IJobHandler<String> jobHandlerDirect = new JobHandlerDirect();//同步的        IJobHandler<String> jobHanderAsync = new JobHandlerAsync<String>(3,500,"JobHand",jobHandlerDirect);//同步转换成异步        jobHanderAsync.doJob("1");        jobHanderAsync.doJob("2");        jobHanderAsync.doJob("3");    }}

 

先告诉我,如果不异步的时候,需要如何处理?实现IJobHandler接口

public interface IJobHandler<T> {public void doJob(T job);}


装饰器JobHandlerAsync是如何把一个同步处理转换成异步处理的

import java.util.List;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.RejectedExecutionHandler;import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class JobHandlerAsync<T> implements JobHandlerAsyncMBean,IJobHandler<T> {private static final Logger log = LoggerFactory.getLogger(JobHandlerAsync.class);private int queueCapacity;private BlockingQueue<Runnable> queue;private ThreadPoolExecutor executor;private IJobHandler<T> delegate;private static final AtomicInteger instanceCount = new AtomicInteger(1);private int instanceNum;public JobHandlerAsync(int fixedThreadSize, int queueCapacity, String threadTag,IJobHandler<T> hbb) {this(hbb, fixedThreadSize, fixedThreadSize, 1000*60*2, threadTag, fixedThreadSize, new LinkedBlockingQueue<Runnable>(queueCapacity));}public JobHandlerAsync(IJobHandler<T> hbb) {/* * 队列大小不宜太大,积压超过50个,立马要增加线程来处理;如果线程增加了,还是处理不过了,基本表示系统后方出问题了。 * 后方出问题了,应该尽管启动拒绝策略,决绝策略可以报警。 * 如果队列设置太大,导致即使处理不过来,也不会增加线程,更不会启动拒绝策略,意思就是:我现在处理不过来了,积压着吧,等我慢慢处理。 * 最终要么是队列增大,设置超过JVM内存,最终因为内存溢出而挂了;要么是客户端长时间等待,客户端认为超时,响应已经没有意义了。 * */this(hbb, 5, 10, 1000*60*2, "JobHandler", 50);}public JobHandlerAsync(IJobHandler<T> hbb, int coreThreadSize, int maxThreadSize, int keepAliveSec,String threadTag, int queueCapacity) {    this(hbb, coreThreadSize, maxThreadSize, keepAliveSec, threadTag, queueCapacity, new LinkedBlockingQueue<Runnable>(queueCapacity));}protected JobHandlerAsync(IJobHandler<T> hbb, int coreThreadSize, int maxThreadSize, int keepAliveSec,String threadTag, int queueCapacity,BlockingQueue<Runnable> queue) {this.threadTag = threadTag;this.delegate = hbb;this.queueCapacity = queueCapacity;this.queue = queue;RejectedExecutionHandler rejectedHandler = new AlertPolicy();ThreadFactory threadFactory = new TagThreadFactory(threadTag);this.executor = new ThreadPoolExecutor(coreThreadSize,maxThreadSize, keepAliveSec, TimeUnit.SECONDS, queue,threadFactory,rejectedHandler);this.instanceNum = instanceCount.getAndIncrement();/* 注册JMX */String beanName = getMBeanName();    if (JmxMBeanManager.getInstance().isRegistered(beanName)) {        log.warn("MBean '{}' is already registered, removing...", beanName);        JmxMBeanManager.getInstance().unregisterMBean(beanName);    }    log.info("Registering MBean '{}'...", beanName);    JmxMBeanManager.getInstance().registerMBean(this, beanName);}private String threadTag; private String getMBeanName() {    //return JMX_MBEAN_OBJ_NAME + "-" + instanceNum;//"com.sohu.tv.live.counter:type=JobHandlerAsync" //com.sohu.tv.utils.threads return "com.sohu.tv.utils.threads:type="+threadTag + "-" + instanceNum; }/** 拒绝策略自己实现的意义:系统处理不过来的时候,可以短信告警,即使发现系统的问题。*/public static class AlertPolicy implements RejectedExecutionHandler  {/* new ThreadPoolExecutor.AbortPolicy() Not Fit */@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {log.warn("reject alert Job: {}", r);//目前登记日志报警,可以发短信的}}/** 线程工厂自己实现的意义:可以统计程序在什么时间段增加了线程;还能给线程起名称(这样jstack看起来方便)。*/public static class TagThreadFactory implements ThreadFactory {/* 代码取自:  Executors.defaultThreadFactory(); */static final AtomicInteger poolNumber = new AtomicInteger(1);        final ThreadGroup group;        final AtomicInteger threadNumber = new AtomicInteger(1);        final String namePrefix;        TagThreadFactory(String tagName) {            SecurityManager s = System.getSecurityManager();            group = (s != null)? s.getThreadGroup() :                                 Thread.currentThread().getThreadGroup();            namePrefix = tagName+"-P"+poolNumber.getAndIncrement() +"T";        }        /**线程名称:Tag-PnTm-timestamp*/        @Override        public Thread newThread(Runnable r) {        String namePostfix = "-"+System.currentTimeMillis();//系统调用,比较消耗性能,但是能标识线程是什么时候创建的        /*标识线程的创建时间,从某种意义上能看出这个线程被复用的程度*/            Thread t = new Thread(group, r,                                  namePrefix + threadNumber.getAndIncrement() + namePostfix,                                  0);            if (t.isDaemon())                t.setDaemon(false);            if (t.getPriority() != Thread.NORM_PRIORITY)                t.setPriority(Thread.NORM_PRIORITY);            return t;        }}@Overridepublic int getActiveThreadSize() {return executor.getActiveCount();}@Overridepublic int getAliveThreadSize() {return executor.getPoolSize();}@Overridepublic int getQueueSize() {return queue.size();}@Overridepublic int getHistoricalPeekThreadSize() {return executor.getLargestPoolSize();}@Overridepublic long getHistoricalTotalTaskCount() {return executor.getTaskCount();}@Overridepublic long getHistoricalCompletedTaskCount() {return executor.getCompletedTaskCount();}@Overridepublic int getCoreThreadSize() {return executor.getCorePoolSize();}@Overridepublic int getMaxThreadSize() {return executor.getMaximumPoolSize();}@Overridepublic int getQueueCapacity() {return queueCapacity;}@Overridepublic void doJob(T job) {executor.execute(new JobRunnable(job));}public class JobRunnable implements Runnable {private final T job;public JobRunnable(T attachment) {this.job = attachment;}@Overridepublic void run() {delegate.doJob(job);}@Overridepublic String toString() {return job.toString();}}@Overridepublic void shutdown() {executor.shutdown();}@Overridepublic List<Runnable> shutdownNow() {return executor.shutdownNow();}}

 

支持JMX管理的Bean,另外为了运维方便,给线程都打上Tag

import java.util.List;public interface JobHandlerAsyncMBean {/* 标准MBean条件:MBean接口和实现必须在同一个包下;实现类和MBean接口名称仅仅相差MBean后缀,接口:ABCMBean,那实现类必须是ABC */String JMX_MBEAN_OBJ_NAME = "com.sohu.tv.live.counter:type=JobHandlerAsync";/* 第一部分:当前信息部分 *//** 返回当前有多少个线程正在忙碌地处理报文 */public int getActiveThreadSize();/** 返回当前有多少个线程是存活的。注意:存活的(Alive)-忙碌的(Active)=空闲的Idle */public int getAliveThreadSize();/** 返回当前队列中积压的作业 */public int getQueueSize();/* 第二部分: 统计信息部分  *//** 返回历史上最高峰值  */public int getHistoricalPeekThreadSize();/** 返回累计到现在处理了多少个Job */public long getHistoricalTotalTaskCount();/** 返回累计到现在处理成功了多少个Job */public long getHistoricalCompletedTaskCount();/* 第三部分: 配置信息部分 *//** 返回最小设置(初始化不一定能到达最小设置的)*/public int getCoreThreadSize();/** 返回最大设置*/public int getMaxThreadSize();/** 返回当前队列的最大容量 */public int getQueueCapacity();public void shutdown();public List<Runnable> shutdownNow();}


 

import java.lang.management.ManagementFactory;import javax.management.MBeanServer;import javax.management.ObjectName;public class JmxMBeanManager {    private static final Object mbsCreateMonitor = new Object();    private static JmxMBeanManager thisObj;    private final MBeanServer mbs;    public JmxMBeanManager() {        mbs = ManagementFactory.getPlatformMBeanServer();    }    public static JmxMBeanManager getInstance() {        synchronized (mbsCreateMonitor) {            if (null == thisObj) {                thisObj = new JmxMBeanManager();            }        }        return thisObj;    }    public boolean isRegistered(String name) {        try {            ObjectName objName = new ObjectName(name);            return mbs.isRegistered(objName);        }        catch (Exception e) {            throw new RuntimeException("exception while checking if MBean is registered, " + name, e);        }    }    public void registerMBean(Object theBean, String name) {        try {            ObjectName objName = new ObjectName(name);            mbs.registerMBean(theBean, objName);        }        catch (Exception e) {            throw new RuntimeException("exception while registering MBean, " + name, e);        }    }    public void unregisterMBean(String name) {        try {            ObjectName objName = new ObjectName(name);            mbs.unregisterMBean(objName);        }        catch (Exception e) {            throw new RuntimeException("exception while unregistering MBean, " + name, e);        }    }    public Object getAttribute(String objName, String attrName) {        try {            ObjectName on = new ObjectName(objName);            return mbs.getAttribute(on, attrName);        }        catch (Exception e) {            throw new RuntimeException("exception while getting MBean attribute, " + objName + ", " + attrName, e);        }    }    public Integer getIntAttribute(String objName, String attrName) {        return (Integer) getAttribute(objName, attrName);    }    public String getStringAttribute(String objName, String attrName) {        return (String) getAttribute(objName, attrName);    }}


 

 

 

 

 

原创粉丝点击