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); }}
- JAVA同步转异步
- Java 异步方法转同步
- java实现异步转同步
- Java同步代码转异步代码
- java同步、异步有关知识点【转】
- java 异步转同步工具类
- java 异步请求转同步结果
- java中的同步与异步(转)
- java 异步 同步应用
- java 同步和异步
- Java同步与异步
- java 同步 异步
- java 异步 同步应用
- Java同步与异步
- java同步 异步 多线程
- java同步和异步
- java 异步 同步应用
- java中的同步与异步
- 认识大数据
- 0040算法笔记——【分支限界法】批处理作业调度问题
- 如何统计输入中所有单词出现的次数?
- MongoDB学习笔记(一) MongoDB介绍及安装
- 悬浮框
- JAVA同步转异步
- flexpaper源码的编译,去除logo和打印
- 堆排序
- CMake的使用方法入门
- 0041算法笔记——【随机化算法】随机化算法与随机数问题
- Spring mvc基于注解的学习
- 图像处理与计算机视觉:基础,经典以及最近发展(1)序
- 公钥,私钥,SSL(讲的很生动)
- wsdl