package com.baidu.adxgate.adx;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ConcurrentTestMain {
public static void main(String[] args) {
// 创建一个延迟队列
DelayQueue<DelayedTaskTest> queue = new DelayQueue<DelayedTaskTest>();
// 初始化线程池
ExecutorService executorService = Executors.newFixedThreadPool(1);
// 初始化延迟队列
for (int i = 1; i <= 20; i++) {
YoukuSubmitRequest youkuSubmit = new YoukuSubmitRequest();
youkuSubmit.setCdnId("cdn_id_" + i);
queue.put(new DelayedTaskTest(youkuSubmit, 10 + i * 100));
}
// 开始模拟
Audition audition = new Audition();
audition.doAudition(queue, executorService);
}
}
/**
* 调用类
* <p>
*
* @author zhoudongdong
* @date 2015年7月31日
*/
class Audition {
/**
* @param queue 延迟队列
* @param executorService 执行任务的线程池
*
* @author zhoudongdong 2015年7月31日
*/
public void doAudition(DelayQueue<DelayedTaskTest> queue, ExecutorService executorService) {
System.out.println("1111111111111111111111111111111111111111");
// 线程池调用 延迟任务唤醒类
executorService.submit(new DelayedTaskInvoker(queue));
System.out.println("222222222222222222222222222222222222222222222");
// shutdown() 方法在终止前允许执行以前提交的任务
// 第一阶段调用 shutdown 拒绝传入任务,然后调用 shutdownNow(如有必要)取消所有遗留的任务
// 提交的任务运行结束后关闭线程池
executorService.shutdown();
System.out.println("3333333333333333333333333333333333333");
}
}
/**
* 延迟任务类
* <p>
*
* @author zhoudongdong
* @date 2015年7月31日
*/
class DelayedTaskTest implements Delayed, Runnable {
/**
* 包含请求信息的bean
*/
private YoukuSubmitRequest youkuSubmitRequest;
/**
* 延迟多久
*/
private final long trigger;
/**
* @param youkuSubmit 包含请求信息的bean
* @param delayInMilliseconds 要延迟的时间 millis
*/
public DelayedTaskTest(YoukuSubmitRequest youkuSubmit, long delayInMilliseconds) {
this.youkuSubmitRequest = youkuSubmit;
this.trigger = System.currentTimeMillis() + delayInMilliseconds;
}
@Override
public void run() {
// 模拟请求接口提交
YoukuResponse respone = Proxy.submintToAdx(youkuSubmitRequest);
// 假设某一个出现问题,不符合条件,需要中断后续DB操作
if (youkuSubmitRequest.getCdnId().equals("cdn_id_10")) {
System.out.println("返回结果为空, 中断该进程");
throw new RuntimeException("中断该进程" + youkuSubmitRequest.getCdnId());
}
if (respone.getResult().equals("OK")) {
System.out.println("提交成功,修改数据库库" + youkuSubmitRequest.getCdnId());
} else {
System.out.println("提交失败");
}
}
// 设定优先级比较方式
@Override
public int compareTo(Delayed o) {
// TODO Auto-generated method stub
DelayedTaskTest that = (DelayedTaskTest) o;
if (this.trigger > that.trigger)
return 1;
if (this.trigger < that.trigger)
return -1;
return 0;
}
// 何时才能被触发
@Override
public long getDelay(TimeUnit unit) {
// TODO Auto-generated method stub
return unit.convert(trigger - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
}
/**
* 延迟任务唤醒类,延迟任务在这里被唤醒
* <p>
*
* @author zhoudongdong
* @date 2015年7月31日
*/
class DelayedTaskInvoker implements Runnable {
/**
* 延迟队列,里面存放延迟任务
*/
private DelayQueue<DelayedTaskTest> dq;
/**
* @param q 延迟队列
*/
public DelayedTaskInvoker(DelayQueue<DelayedTaskTest> q) {
dq = q;
}
@Override
public void run() {
// 线程没有被中断,且延迟队列不为空
while (!Thread.interrupted() && !dq.isEmpty()) {
try {
// 从延迟队列中取出延迟任务,并且唤醒它,让其执行任务
dq.take().run();
} catch (Exception e) {
// 监测该延迟任务可能抛出的异常
e.printStackTrace();
}
}
System.out.println("finished delayedtask consume!!!!!");
}
}
/**
* 模拟的接口代理类
* <p>
*
* @author zhoudongdong
* @date 2015年7月31日
*/
class Proxy {
/**
* 模拟请求优酷ADX接口,提交创意,并接收到结果
*
* @param youkuSubmit 包含要提交的信息的bean
* @return YoukuResponse ADX返回的结果
*
* @author zhoudongdong 2015年7月31日
*/
public static YoukuResponse submintToAdx(YoukuSubmitRequest youkuSubmit) {
// 模拟ADX返回结果
YoukuResponse youkuResponse = new YoukuResponse();
youkuResponse.setResult("OK");
System.out.println("proxy submit " + youkuSubmit.getCdnId());
return youkuResponse;
}
}
/**
* 包含请求信息的Bean
* <p>
*
* @author zhoudongdong
* @date 2015年7月31日
*/
class YoukuSubmitRequest {
/**
* 在CDN中的ID
*/
private String cdnId;
/**
* @return the cdnId
*/
public String getCdnId() {
return cdnId;
}
/**
* @param cdnId the cdnId to set
*/
public void setCdnId(String cdnId) {
this.cdnId = cdnId;
}
}
/**
* 接收调用ADX接口后返回的结果
* <p>
*
* @author zhoudongdong
* @date 2015年7月31日
*/
class YoukuResponse {
/**
* 审核结果
*/
private String result;
/**
* @return the result
*/
public String getResult() {
return result;
}
/**
* @param result the result to set
*/
public void setResult(String result) {
this.result = result;
}
}
1111111111111111111111111111111111111111
222222222222222222222222222222222222222222222
3333333333333333333333333333333333333
proxy submit cdn_id_1
提交成功,修改数据库库cdn_id_1
proxy submit cdn_id_2
提交成功,修改数据库库cdn_id_2
proxy submit cdn_id_3
提交成功,修改数据库库cdn_id_3
proxy submit cdn_id_4
提交成功,修改数据库库cdn_id_4
proxy submit cdn_id_5
提交成功,修改数据库库cdn_id_5
proxy submit cdn_id_6
提交成功,修改数据库库cdn_id_6
proxy submit cdn_id_7
提交成功,修改数据库库cdn_id_7
proxy submit cdn_id_8
提交成功,修改数据库库cdn_id_8
proxy submit cdn_id_9
提交成功,修改数据库库cdn_id_9
proxy submit cdn_id_10
返回结果为空, 中断该进程
java.lang.RuntimeException: 中断该进程cdn_id_10
at com.baidu.adxgate.adx.DelayedTaskTest.run(ConcurrentTestMain.java:101)
at com.baidu.adxgate.adx.DelayedTaskInvoker.run(ConcurrentTestMain.java:160)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
proxy submit cdn_id_11
提交成功,修改数据库库cdn_id_11
proxy submit cdn_id_12
提交成功,修改数据库库cdn_id_12
proxy submit cdn_id_13
提交成功,修改数据库库cdn_id_13
proxy submit cdn_id_14
提交成功,修改数据库库cdn_id_14
proxy submit cdn_id_15
提交成功,修改数据库库cdn_id_15
proxy submit cdn_id_16
提交成功,修改数据库库cdn_id_16
proxy submit cdn_id_17
提交成功,修改数据库库cdn_id_17
proxy submit cdn_id_18
提交成功,修改数据库库cdn_id_18
proxy submit cdn_id_19
提交成功,修改数据库库cdn_id_19
proxy submit cdn_id_20
提交成功,修改数据库库cdn_id_20
finished delayedtask run!!!!!