充值,提現功能涉及的多線程、隊列問題
阿新 • • 發佈:2017-09-05
override ring cut mov tlist ini nco 同步 exceptio
使用雙乾第三方實現充值,提現功能。
思路
配置一個監聽器在項目啟動時初始化一個隊列,開一個線程(run方法中檢查隊列中是否有值,有的話執行業務,沒有的話線程等待)。充值,提現成功後回調方法時,填充隊列,喚醒等待線程執行業務方法。
實現
web.xml中配置一個監聽器
<listener>
<listener-class>com.wjz.listener.MyWebConfigContextListener</listener-class> </listener>
MyWebConfigContextListener監聽器
package com.wjz.listener;import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.wjz.queue.MyCashJobQueue; import com.wjz.service.MyAccountService;import com.wjz.service.MyUserService; public class MyWebConfigContextListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); MyUserService userService= (MyUserService) context.getBean("userService"); MyAccountService accountService = (MyAccountService) context.getBean("accountService"); //初始化業務處理隊列 MyCashJobQueue.init(userService, accountService); } }
MyCashJobQueue功能隊列
package com.wjz.queue; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import com.wjz.model.MyCashModel; import com.wjz.service.MyAccountService; import com.wjz.service.MyUserService; import com.wjz.task.MyTask; import com.wjz.task.impl.MyCashTask; /** * @author wjz */ public class MyCashJobQueue<T> { @SuppressWarnings({ "rawtypes", "unchecked" }) private Queue<T> queue = new ConcurrentLinkedQueue(); private MyTask task; public MyCashJobQueue(MyTask task) { this.task = task; } public static MyCashJobQueue<MyCashModel> CASH_QUEUE = null;
// 初始化一個任務對象註入到功能隊列中,任務對象開線程 public static void init(MyUserService userService, MyAccountService accountService) { CASH_QUEUE = new MyCashJobQueue<MyCashModel>(new MyCashTask(userService, accountService)); } public int size() { return queue.size(); } public synchronized T peek() { return (T) queue.peek(); } public synchronized T remove(T model) { return queue.remove(); } // 向隊列中填充值,喚醒等待線程
// 同步MyCashJobQueue的實例對象 public synchronized void offer(T model) { if (!queue.contains(model)) { queue.offer(model);
// 同步內容 synchronized (task.getLock()) { task.execute(); } } } }
MyTask任務接口
package com.wjz.task; public interface MyTask { public static final String CASH_STATUS = "cash_status"; public void execute(); public void doRun(); public void doWait(); public void stop(); public Object getLock(); }
充值,提現功能實現類
package com.wjz.task.impl; import com.wjz.model.MyCashModel; import com.wjz.queue.MyCashJobQueue; import com.wjz.service.MyAccountService; import com.wjz.service.MyUserService; import com.wjz.task.MyAbstractTask; import com.wjz.task.MyTask; public class MyCashTask extends MyAbstractTask { private MyUserService userService; private MyAccountService accountService; @Override public void doRun() { while (MyCashJobQueue.CASH_QUEUE != null && MyCashJobQueue.CASH_QUEUE.size() > 0) { // 取出隊列中的任務 MyCashModel cashModel = MyCashJobQueue.CASH_QUEUE.peek(); try { if (cashModel != null) { // 業務處理 accountService.doRechargeTask(); } } catch (Exception e) { } finally { // 去除隊列中的任務 MyCashJobQueue.CASH_QUEUE.remove(cashModel); } } } public MyCashTask(MyUserService userService, MyAccountService accountService) { super(); this.userService = userService; this.accountService = accountService; } @Override public Object getLock() { return MyTask.CASH_STATUS; } }
充值,提現功能涉及的多線程、隊列問題