面試官:生成訂單30分鐘未支付,則自動取消,該怎么實現(xiàn)?

-? ? ?前言? ? -

生成訂單30分鐘未支付,則自動取消 生成訂單60秒后,給用戶發(fā)短信

-? ? ?方案分析? ? -
(1)數(shù)據(jù)庫輪詢
思路
????org.quartz-scheduler
????quartz
????2.2.2
package?com.rjzheng.delay1;
import?org.quartz.JobBuilder;
import?org.quartz.JobDetail;
import?org.quartz.Scheduler;
import?org.quartz.SchedulerException;
import?org.quartz.SchedulerFactory;
import?org.quartz.SimpleScheduleBuilder;
import?org.quartz.Trigger;
import?org.quartz.TriggerBuilder;
import?org.quartz.impl.StdSchedulerFactory;
import?org.quartz.Job;
import?org.quartz.JobExecutionContext;
import?org.quartz.JobExecutionException;
public?class?MyJob?implements?Job?{
????public?void?execute(JobExecutionContext?context)
????????????throws?JobExecutionException?{
????????System.out.println("要去數(shù)據(jù)庫掃描啦。。。");
????}
????public?static?void?main(String[]?args)?throws?Exception?{
????????//?創(chuàng)建任務(wù)
????????JobDetail?jobDetail?=?JobBuilder.newJob(MyJob.class)
????????????????.withIdentity("job1",?"group1").build();
????????//?創(chuàng)建觸發(fā)器?每3秒鐘執(zhí)行一次
????????Trigger?trigger?=?TriggerBuilder
????????????????.newTrigger()
????????????????.withIdentity("trigger1",?"group3")
????????????????.withSchedule(
????????????????????????SimpleScheduleBuilder.simpleSchedule()
????????????????????????????????.withIntervalInSeconds(3).repeatForever())
????????????????.build();
????????Scheduler?scheduler?=?new?StdSchedulerFactory().getScheduler();
????????//?將任務(wù)及其觸發(fā)器放入調(diào)度器
????????scheduler.scheduleJob(jobDetail,?trigger);
????????//?調(diào)度器開始調(diào)度任務(wù)
????????scheduler.start();
????}
}
(2)JDK的延遲隊列

-? ? ?思路? ? -


-? ? ?實現(xiàn)? ? -
package?com.rjzheng.delay2;
import?java.util.concurrent.Delayed;
import?java.util.concurrent.TimeUnit;
public?class?OrderDelay?implements?Delayed?{
????private?String?orderId;
????private?long?timeout;
????OrderDelay(String?orderId,?long?timeout)?{
????????this.orderId?=?orderId;
????????this.timeout?=?timeout?+?System.nanoTime();
????}
????public?int?compareTo(Delayed?other)?{
????????if?(other?==?this)
????????????return?0;
????????OrderDelay?t?=?(OrderDelay)?other;
????????long?d?=?(getDelay(TimeUnit.NANOSECONDS)?-?t
????????????????.getDelay(TimeUnit.NANOSECONDS));
????????return?(d?==?0)???0?:?((d?0)???-1?:?1);
????}
????//?返回距離你自定義的超時時間還有多少
????public?long?getDelay(TimeUnit?unit)?{
????????return?unit.convert(timeout?-?System.nanoTime(),TimeUnit.NANOSECONDS);
????}
????void?print()?{
????????System.out.println(orderId+"編號的訂單要刪除啦。。。。");
????}
}
package?com.rjzheng.delay2;
import?java.util.ArrayList;
import?java.util.List;
import?java.util.concurrent.DelayQueue;
import?java.util.concurrent.TimeUnit;
public?class?DelayQueueDemo?{
?????public?static?void?main(String[]?args)?{??
????????????//?TODO?Auto-generated?method?stub??
????????????List?list?=?new?ArrayList ();??
????????????list.add("00000001");??
????????????list.add("00000002");??
????????????list.add("00000003");??
????????????list.add("00000004");??
????????????list.add("00000005");??
????????????DelayQueue?queue?=?newDelayQueue ();??
????????????long?start?=?System.currentTimeMillis();??
????????????for(int?i?=?0;i<5;i++){??
????????????????//延遲三秒取出
????????????????queue.put(new?OrderDelay(list.get(i),??
????????????????????????TimeUnit.NANOSECONDS.convert(3,TimeUnit.SECONDS)));??
????????????????????try?{??
?????????????????????????queue.take().print();??
?????????????????????????System.out.println("After?"?+??
?????????????????????????????????(System.currentTimeMillis()-start)?+?"?MilliSeconds");??
????????????????}?catch?(InterruptedException?e)?{??
????????????????????//?TODO?Auto-generated?catch?block??
????????????????????e.printStackTrace();??
????????????????}??
????????????}??
????????}??
}
00000001編號的訂單要刪除啦。。。。
After?3003?MilliSeconds
00000002編號的訂單要刪除啦。。。。
After?6006?MilliSeconds
00000003編號的訂單要刪除啦。。。。
After?9006?MilliSeconds
00000004編號的訂單要刪除啦。。。。
After?12008?MilliSeconds
00000005編號的訂單要刪除啦。。。。
After?15009?MilliSeconds

????io.netty
????netty-all
????4.1.24.Final
package?com.rjzheng.delay3;
import?io.netty.util.HashedWheelTimer;
import?io.netty.util.Timeout;
import?io.netty.util.Timer;
import?io.netty.util.TimerTask;
import?java.util.concurrent.TimeUnit;
public?class?HashedWheelTimerTest?{
????static?class?MyTimerTask?implements?TimerTask{
????????boolean?flag;
????????public?MyTimerTask(boolean?flag){
????????????this.flag?=?flag;
????????}
????????public?void?run(Timeout?timeout)?throws?Exception?{
????????????//?TODO?Auto-generated?method?stub
?????????????System.out.println("要去數(shù)據(jù)庫刪除訂單了。。。。");
?????????????this.flag?=false;
????????}
????}
????public?static?void?main(String[]?argv)?{
????????MyTimerTask?timerTask?=?new?MyTimerTask(true);
????????Timer?timer?=?new?HashedWheelTimer();
????????timer.newTimeout(timerTask,?5,?TimeUnit.SECONDS);
????????int?i?=?1;
????????while(timerTask.flag){
????????????try?{
????????????????Thread.sleep(1000);
????????????}?catch?(InterruptedException?e)?{
????????????????//?TODO?Auto-generated?catch?block
????????????????e.printStackTrace();
????????????}
????????????System.out.println(i+"秒過去了");
????????????i++;
????????}
????}
}
1秒過去了
2秒過去了
3秒過去了
4秒過去了
5秒過去了
要去數(shù)據(jù)庫刪除訂單了。。。。
6秒過去了
添加單個元素
redis>?ZADD?page_rank?10?google.com
(integer)?1
添加多個元素
redis>?ZADD?page_rank?9?baidu.com?8?bing.com
(integer)?2
redis>?ZRANGE?page_rank?0?-1?WITHSCORES
1)?"bing.com"
2)?"8"
3)?"baidu.com"
4)?"9"
5)?"google.com"
6)?"10"
查詢元素的score值
redis>?ZSCORE?page_rank?bing.com
"8"
移除單個元素
redis>?ZREM?page_rank?google.com
(integer)?1
redis>?ZRANGE?page_rank?0?-1?WITHSCORES
1)?"bing.com"
2)?"8"
3)?"baidu.com"
4)?"9"

package?com.rjzheng.delay4;
import?java.util.Calendar;
import?java.util.Set;
import?redis.clients.jedis.Jedis;
import?redis.clients.jedis.JedisPool;
import?redis.clients.jedis.Tuple;
public?class?AppTest?{
????private?static?final?String?ADDR?=?"127.0.0.1";
????private?static?final?int?PORT?=?6379;
????private?static?JedisPool?jedisPool?=?new?JedisPool(ADDR,?PORT);
????public?static?Jedis?getJedis()?{
???????return?jedisPool.getResource();
????}
????//生產(chǎn)者,生成5個訂單放進去
????public?void?productionDelayMessage(){
????????for(int?i=0;i<5;i++){
????????????//延遲3秒
????????????Calendar?cal1?=?Calendar.getInstance();
????????????cal1.add(Calendar.SECOND,?3);
????????????int?second3later?=?(int)?(cal1.getTimeInMillis()?/?1000);
????????????AppTest.getJedis().zadd("OrderId",second3later,"OID0000001"+i);
????????????System.out.println(System.currentTimeMillis()+"ms:redis生成了一個訂單任務(wù):訂單ID為"+"OID0000001"+i);
????????}
????}
????//消費者,取訂單
????public?void?consumerDelayMessage(){
????????Jedis?jedis?=?AppTest.getJedis();
????????while(true){
????????????Set?items?=?jedis.zrangeWithScores("OrderId",?0,?1);
????????????if(items?==?null?||?items.isEmpty()){
????????????????System.out.println("當前沒有等待的任務(wù)");
????????????????try?{
????????????????????Thread.sleep(500);
????????????????}?catch?(InterruptedException?e)?{
????????????????????//?TODO?Auto-generated?catch?block
????????????????????e.printStackTrace();
????????????????}
????????????????continue;
????????????}
????????????int??score?=?(int)?((Tuple)items.toArray()[0]).getScore();
????????????Calendar?cal?=?Calendar.getInstance();
????????????int?nowSecond?=?(int)?(cal.getTimeInMillis()?/?1000);
????????????if(nowSecond?>=?score){
????????????????String?orderId?=?((Tuple)items.toArray()[0]).getElement();
????????????????jedis.zrem("OrderId",?orderId);
????????????????System.out.println(System.currentTimeMillis()?+"ms:redis消費了一個任務(wù):消費的訂單OrderId為"+orderId);
????????????}
????????}
????}
????public?static?void?main(String[]?args)?{
????????AppTest?appTest?=new?AppTest();
????????appTest.productionDelayMessage();
????????appTest.consumerDelayMessage();
????}
}

package?com.rjzheng.delay4;
import?java.util.concurrent.CountDownLatch;
public?class?ThreadTest?{
????private?static?final?int?threadNum?=?10;
????private?static?CountDownLatch?cdl?=?newCountDownLatch(threadNum);
????static?class?DelayMessage?implements?Runnable{
????????public?void?run()?{
????????????try?{
????????????????cdl.await();
????????????}?catch?(InterruptedException?e)?{
????????????????//?TODO?Auto-generated?catch?block
????????????????e.printStackTrace();
????????????}
????????????AppTest?appTest?=new?AppTest();
????????????appTest.consumerDelayMessage();
????????}
????}
????public?static?void?main(String[]?args)?{
????????AppTest?appTest?=new?AppTest();
????????appTest.productionDelayMessage();
????????for(int?i=0;i
????????????new?Thread(new?DelayMessage()).start();
????????????cdl.countDown();
????????}
????}
}

if(nowSecond?>=?score){
????String?orderId?=?((Tuple)items.toArray()[0]).getElement();
????jedis.zrem("OrderId",?orderId);
????System.out.println(System.currentTimeMillis()+"ms:redis消費了一個任務(wù):消費的訂單OrderId為"+orderId);
}
if(nowSecond?>=?score){
????String?orderId?=?((Tuple)items.toArray()[0]).getElement();
????Long?num?=?jedis.zrem("OrderId",?orderId);
????if(?num?!=?null?&&?num>0){
????????System.out.println(System.currentTimeMillis()+"ms:redis消費了一個任務(wù):消費的訂單OrderId為"+orderId);
????}
}
package?com.rjzheng.delay5;
import?redis.clients.jedis.Jedis;
import?redis.clients.jedis.JedisPool;
import?redis.clients.jedis.JedisPubSub;
public?class?RedisTest?{
????private?static?final?String?ADDR?=?"127.0.0.1";
????private?static?final?int?PORT?=?6379;
????private?static?JedisPool?jedis?=?new?JedisPool(ADDR,?PORT);
????private?static?RedisSub?sub?=?new?RedisSub();
????public?static?void?init()?{
????????new?Thread(new?Runnable()?{
????????????public?void?run()?{
????????????????jedis.getResource().subscribe(sub,?"__keyevent@0__:expired");
????????????}
????????}).start();
????}
????public?static?void?main(String[]?args)?throws?InterruptedException?{
????????init();
????????for(int?i?=0;i<10;i++){
????????????String?orderId?=?"OID000000"+i;
????????????jedis.getResource().setex(orderId,?3,?orderId);
????????????System.out.println(System.currentTimeMillis()+"ms:"+orderId+"訂單生成");
????????}
????}
????static?class?RedisSub?extends?JedisPubSub?{
????????'http://www.jobbole.com/members/wx610506454' >@Override
????????public?void?onMessage(String?channel,?String?message)?{
????????????System.out.println(System.currentTimeMillis()+"ms:"+message+"訂單取消");
????????}
????}
}

作者:hjm4702192
來源:
blog.csdn.net/hjm4702192/article/details/80519010
評論
圖片
表情
