充值,提现功能涉及的多线程、队列问题
使用双乾第三方实现充值,提现功能。
思路
配置一个监听器在项目启动时初始化一个队列,开一个线程(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; } }