java 订单队列_javaWeb 使用线程池+队列解决"订单并发"问题

解决方式:使用线程池+队列

项目基于Spring,如果不用spring需要自己把

ThreadPoolManager.java

改成单例模式

1.写一个Controller(Spring mvc)

/**

* @author HeyS1

* @date 2016/12/1

* @description

*/

@Controller

public class ThreadPoolController {

@Autowired

ThreadPoolManager tpm;

@RequestMapping("/pool") public @ResponseBody Object test() { for (int i = 0; i < 500; i++) {   //模拟并发500条记录 tpm.processOrders(Integer.toString(i)); } return "ok"; } }

2.线程池管理

/**

* @author HeyS1

* @date 2016/12/1

* @description threadPool订单线程池, 处理订单

* scheduler 调度线程池 用于处理订单线程池由于超出线程范围和队列容量而不能处理的订单

*/

@Component public class ThreadPoolManager implements BeanFactoryAware { private static Logger log = LoggerFactory.getLogger(ThreadPoolManager.class); private BeanFactory factory;//用于从IOC里取对象 // 线程池维护线程的最少数量 private final static int CORE_POOL_SIZE = 2; // 线程池维护线程的最大数量 private final static int MAX_POOL_SIZE = 10; // 线程池维护线程所允许的空闲时间 private final static int KEEP_ALIVE_TIME = 0; // 线程池所使用的缓冲队列大小 private final static int WORK_QUEUE_SIZE = 50; // 消息缓冲队列 Queue msgQueue = new LinkedList(); //用于储存在队列中的订单,防止重复提交 Map cacheMap = new ConcurrentHashMap<>(); //由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序 final RejectedExecutionHandler handler = new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { //System.out.println("太忙了,把该订单交给调度线程池逐一处理" + ((DBThread) r).getMsg()); msgQueue.offer(((DBThread) r).getMsg()); } }; // 订单线程池 final ThreadPoolExecutor threadPool = new ThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue(WORK_QUEUE_SIZE), this.handler); // 调度线程池。此线程池支持定时以及周期性执行任务的需求。 final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5); // 访问消息缓存的调度线程,每秒执行一次 // 查看是否有待定请求,如果有,则创建一个新的AccessDBThread,并添加到线程池中 final ScheduledFuture taskHandler = scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { if (!msgQueue.isEmpty()) { if (threadPool.getQueue().size() < WORK_QUEUE_SIZE) { System.out.print("调度:"); String orderId = (String) msgQueue.poll(); DBThread accessDBThread = (DBThread) factory.getBean("dBThread"); accessDBThread.setMsg(orderId); threadPool.execute(accessDBThread); } // while (msgQueue.peek() != null) { // } } } }, 0, 1, TimeUnit.SECONDS); //终止订单线程池+调度线程池 public void shutdown() { //true表示如果定时任务在执行,立即中止,false则等待任务结束后再停止 System.out.println(taskHandler.cancel(false)); scheduler.shutdown(); threadPool.shutdown(); } public Queue getMsgQueue() { return msgQueue; } //将任务加入订单线程池 public void processOrders(String orderId) { if (cacheMap.get(orderId) == null) { cacheMap.put(orderId,new Object()); DBThread accessDBThread = (DBThread) factory.getBean("dBThread"); accessDBThread.setMsg(orderId); threadPool.execute(accessDBThread); } } //BeanFactoryAware @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { factory = beanFactory; } }

3.线程池中工作的线程

//线程池中工作的线程

@Component

@Scope("prototype")//spring 多例 public class DBThread implements Runnable { private String msg; private Logger log = LoggerFactory.getLogger(DBThread.class); @Autowired SystemLogService systemLogService; @Override public void run() { //模拟在数据库插入数据 Systemlog systemlog = new Systemlog(); systemlog.setTime(new Date()); systemlog.setLogdescribe(msg); //systemLogService.insert(systemlog); log.info("insert->" + msg); } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }

浏览器输入地址127.0.0.1/pool

4cabb9edd3ef9c894125023915f88958.png

几秒后关闭tomcat。

模拟500条数据,订单线程池处理了117条。调度线程池处理5条

41e4c0f695b2c422ae0e98aa7ba5ee65.png

关闭tomcat,后还有378条未处理(这里的实现需要用到spring监听器)。加起来一共500

OK。完毕

spring监听器,监听tomcat关闭事件:

public class MyApplicationListener implements ApplicationListener { @Autowired ThreadPoolManager threadPoolManager; @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ContextClosedEvent) { XmlWebApplicationContext x = (XmlWebApplicationContext) event.getSource(); //防止执行两次。root application context 没有parent,他就是老大 if (x.getDisplayName().equals("Root WebApplicationContext")) { threadPoolManager.shutdown(); Queue q = threadPoolManager.getMsgQueue(); System.out.println("关闭了服务器,还有未处理的信息条数:" + q.size()); } } else if (event instanceof ContextRefreshedEvent) { // System.out.println(event.getClass().getSimpleName()+" 事件已发生!"); } else if (event instanceof ContextStartedEvent) { // System.out.println(event.getClass().getSimpleName()+" 事件已发生!"); } else if (event instanceof ContextStoppedEvent) { // System.out.println(event.getClass().getSimpleName()+" 事件已发生!"); } else { // System.out.println("有其它事件发生:"+event.getClass().getName()); } } }

spring配置一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.sql.*; public class system extends JFrame { JDesktopPane deskpane = new JDesktopPane();//在窗体里建立虚拟桌 JPanel p = new JPanel();//创建一个面板并实例化 public system(){//构造函数 setTitle("订单管理系统");//设置窗体标题 Container con = getContentPane(); con.setLayout(new BorderLayout());//创建一个布局 con.add(deskpane,BorderLayout.CENTER);//实例虚拟桌面的布局 Font f =new Font("新宋体",Font.PLAIN,12); JMenuBar mb = new JMenuBar();//实例化菜单栏 mb.setOpaque(true); setJMenuBar(mb); mb.setOpaque(true); setJMenuBar(mb); JMenu systemM = new JMenu("系统管理"); systemM.setFont(f); mb.add(systemM); JMenuItem land = new JMenuItem("重新登陆"); land.setFont(f); JMenuItem exit = new JMenuItem("退出系统"); exit.setFont(f); systemM.add(land); systemM.add(exit); JMenu userM = new JMenu("用户管理"); userM.setFont(f); mb.add(userM); JMenuItem password = new JMenuItem("密码修改"); password.setFont(f); JMenuItem addDelete = new JMenuItem("添加/删除用户"); addDelete.setFont(f); userM.add(password); userM.add(addDelete); JMenu mesM = new JMenu("信息管理"); mesM .setFont(f); mb.add(mesM ); JMenu addM= new JMenu("添加信息"); addM.setFont(f); JMenu viewM = new JMenu("查看信息"); viewM.setFont(f); JMenu modifM = new JMenu("修改信息"); modifM.setFont(f); JMenu deleteM = new JMenu("删除信息"); deleteM.setFont(f); mesM.add(addM); mesM.add(viewM); mesM.add(modifM); mesM.add(deleteM); JMenuItem addgoods = new JMenuItem("添加商品信息"); addgoods.setFont(f); addM.add(addgoods); JMenuItem addclient = new JMenuItem("添加客户信息"); addclient.setFont(f); addM.add(addclient); JMenuItem viewgoods= new JMenuItem("查看商品信息"); viewgoods.setFont(f); viewM.add(viewgoods); JMenuItem viewclient = new JMenuItem("查看客户信息"); viewclient.setFont(f); viewM.add(viewclient); JMenuItem modifgoods = new JMenuItem("修改商品信息"); modifgoods.setFont(f); modifM.add(modifgoods); JMenuItem modifclient = new JMenuItem("修改用户信息"); modifclient.setFont(f); modifM.add(modifclient); JMenuItem deletegoods = new JMenuItem("删除商品信息"); deletegoods.setFont(f); deleteM.add(deletegoods); JMenuItem deleteclient = new JMenuItem("删除用户信息"); deleteclient.setFont(f); deleteM.add(deleteclient); JMenu orderM = new JMenu("订单管理"); orderM.setFont(f); mb.add(orderM); JMenuItem addO= new JMenuItem("添加订单"); addO.setFont(f); JMenuItem viewO = new JMenuItem("查看订单"); viewO.setFont(f); JMenuItem modifO = new JMenuItem("修改订单"); modifO.setFont(f); JMenuItem deleteO = new JMenuItem("删除订单"); deleteO.setFont(f); orderM.add(addO); orderM.add(viewO); orderM.add(modifO); orderM.add(deleteO); //主界面上标出学号、姓名、及所作系统名 JLabel jlabel1=new JLabel(); jlabel1.setFont(new Font("宋体",Font.BOLD,15)); //设置字体 jlabel1.setHorizontalAlignment(SwingConstants.CENTER); //设置位置 jlabel1.setText("简易订单管理系统学号:070810228" + " 姓名:廖太春指导老师:周老师"); jlabel1.setBounds(450,350, 200, 200); deskpane.add(jlabel1); password.addActionListener(new ActionListener(){//密码修改监听 public void actionPerformed(ActionEvent e){ System.out.println("修改密码"); deskpane.add(new modifpsw()); } }); land.addActionListener(new ActionListener(){//重新登陆监听 public void actionPerformed(ActionEvent e){ System.out.println("登录"); setVisible(false); new Land(); } }); addDelete.addActionListener(new ActionListener(){//添加/删除用户监听 public void actionPerformed(ActionEvent e){ deskpane.add(new AddDeleteUser()); } }); addgoods.addActionListener(new ActionListener(){//添加商品信息 public void actionPerformed(ActionEvent e){ deskpane.add(new addgoods()); } }); addclient.addActionListener(new ActionListener(){//添加用户信息 public void actionPerformed(ActionEvent e){ deskpane.add(new addclient()); } }); viewgoods.addActionListener(new ActionListener(){//查看商品信息 public void actionPerformed(ActionEvent e){ System.out.println("查看商品信息"); deskpane.add(new viewgoods()); } }); viewclient.addActionListener(new ActionListener(){//查看客户信息 public void actionPerformed(ActionEvent e){ System.out.println("查看客户信息"); deskpane.add(new viewclient()); } }); modifgoods.addActionListener(new ActionListener(){//修改商品信息 public void actionPerformed(ActionEvent e){ System.out.println("修改商品信息"); deskpane.add(new modifgoods()); } }); modifclient.addActionListener(new ActionListener(){//修改用户信息 public void actionPerformed(ActionEvent e){ System.out.println("修改用户信息"); deskpane.add(new modifclient()); } }); deletegoods.addActionListener(new ActionListener(){//删除商品信息 public void actionPerformed(ActionEvent e){ System.out.println("删除商品信息"); deskpane.add(new deletegoods()); } }); deleteclient.addActionListener(new ActionListener(){//删除用户信息 public void actionPerformed(ActionEvent e){ System.out.println("删除用户信息"); deskpane.add(new deleteclient()); } }); addO.addActionListener(new ActionListener(){//添加订单 public void actionPerformed(ActionEvent e){ deskpane.add(new addO()); } }); viewO.addActionListener(new ActionListener(){//查看订单 public void actionPerformed(ActionEvent e){ deskpane.add(new viewO()); } }); modifO.addActionListener(new ActionListener(){//修改订单 public void actionPerformed(ActionEvent e){ System.out.println("修改订单"); deskpane.add(new modifO()); } }); deleteO.addActionListener(new ActionListener(){//删除订单 public void actionPerformed(ActionEvent e){ System.out.println("/删除订单"); deskpane.add(new deleteO()); } }); exit.addActionListener(new ActionListener(){//退出系统监听 public void actionPerformed(ActionEvent e){ setVisible(false); } }); this.setBounds(200,200,700,600); setVisible(true); } public static void main(String[] args){ new Land(); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值