使用ThreadPoolExecutor和Callable的总结

最近一直在研究多线程,走了很多坑,总算把多线程的使用搞清楚了。

阿里的开发文档对多线程的创建强制使用ThreadPoolExecutor,相比Executors,前者更直观的展现多线程内部的运行机制,且也可以合理的运用资源。

下面把代码贴上,简单说下练习中遇到的问题。

public class ThreadControl extends HttpServlet{
    private String id;
    private String no;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {    
        PrintWriter out = resp.getWriter();
        resp.setContentType("text/html;charset=utf-8");
        out = resp.getWriter();
        id=req.getParameter("id");
        no=req.getParameter("pageNo");
        LinkedList<Future<List<User>>> list=new LinkedList<>();    
        ThreadPoolExecutor threadPool=new ThreadPools().getThreadPool();
        try {
            if(null!=id || null!=no||id.equals("")){
                CallBleTest call = new CallBleTest(id, no);    
                Future<List<User>> fur = threadPool.submit(call);                    
                list.add( fur);            
            }
            Iterator<Future<List<User>>> tor = list.iterator();    
            while (tor.hasNext()) {
                Future<List<User>> fu = tor.next();
                List<User> li = fu.get();
                StringBuffer str=new StringBuffer();
                Iterator<User> users = li.iterator();
                while (users.hasNext()) {
                    User user = users.next();
                    str.append(user.toString());                
                }
                out.print(str);
                out.flush();
                out.close();                
            }    
             System.out.println("线程池中线程数目:"+threadPool.getPoolSize()+",队列中等待执行的任务数目:"+
                     threadPool.getQueue().size()+",已执行的任务数目:"+threadPool.getCompletedTaskCount());
        } catch (Exception e) {
            // TODO: handle exception
        }finally {
//            threadPool.shutdown();
        }
    }
}

标红的是遇到问题的地方,之前刚开始时线程池是直接在doPost方法创建的,但是运行后发现出现很多线程池,这里的错误是每次有请求到这个方法,都会创建一个新的线程池,所以我给线程池的写了单利模式创建。把 threadPool.shutdown();注掉是因为把线程关掉后就没办法进行复用了。

public class ThreadPools {
 public static    ThreadPoolExecutor threadPool;
 
    public ThreadPools() {
        // TODO Auto-generated constructor stub
    }
    public synchronized ThreadPoolExecutor getThreadPool() {
        if(null==threadPool){
            threadPool = new ThreadPoolExecutor(3, 5, 200, TimeUnit.MILLISECONDS,
                     new ArrayBlockingQueue<Runnable>(4));
        }        
        return threadPool;    
    }
}

运行后

线程 pool-1-thread-1开始执行Mon Oct 29 17:29:06 CST 2018获取页数1
线程 pool-1-thread-2开始执行Mon Oct 29 17:29:07 CST 2018获取页数2
线程 pool-1-thread-3开始执行Mon Oct 29 17:29:08 CST 2018获取页数3
线程 pool-1-thread-4开始执行Mon Oct 29 17:29:13 CST 2018获取页数3
线程 pool-1-thread-5开始执行Mon Oct 29 17:29:14 CST 2018获取页数4
线程 pool-1-thread-1结束执行Mon Oct 29 17:29:16 CST 2018获取页数 :1 参数DaoTest [name=lidan, age=26, phone=13852014259, addr=null, id=null]DaoTest [name=yangjian, age=24, phone=13852014256, addr=null, id=null]
线程 pool-1-thread-1开始执行Mon Oct 29 17:29:16 CST 2018获取页数4
线程池中线程数目:5,队列中等待执行的任务数目:3,已执行的任务数目:1
线程 pool-1-thread-2结束执行Mon Oct 29 17:29:17 CST 2018获取页数 :2 参数DaoTest [name=li]jian, age=24, phone=13852014259, addr=null, id=null]DaoTest [name=huangjian, age=24, phone=13852014259, addr=null, id=null]
线程 pool-1-thread-2开始执行Mon Oct 29 17:29:17 CST 2018获取页数5
线程池中线程数目:5,队列中等待执行的任务数目:2,已执行的任务数目:2
线程 pool-1-thread-3结束执行Mon Oct 29 17:29:18 CST 2018获取页数 :3 参数DaoTest [name=yangjian, age=24, phone=13852014256, addr=null, id=null]DaoTest [name=yangy, age=24, phone=13852014257, addr=null, id=null]
线程 pool-1-thread-3开始执行Mon Oct 29 17:29:18 CST 2018获取页数1
线程池中线程数目:5,队列中等待执行的任务数目:1,已执行的任务数目:3
线程 pool-1-thread-4结束执行Mon Oct 29 17:29:23 CST 2018获取页数 :3 参数DaoTest [name=yangjian, age=24, phone=13852014256, addr=null, id=null]DaoTest [name=yangy, age=24, phone=13852014257, addr=null, id=null]
线程 pool-1-thread-4开始执行Mon Oct 29 17:29:23 CST 2018获取页数2
线程池中线程数目:5,队列中等待执行的任务数目:0,已执行的任务数目:4
线程 pool-1-thread-5结束执行Mon Oct 29 17:29:24 CST 2018获取页数 :4 参数DaoTest [name=li]jian, age=24, phone=13852014259, addr=null, id=null]DaoTest [name=huangjian, age=24, phone=13852014259, addr=null, id=null]
线程池中线程数目:5,队列中等待执行的任务数目:0,已执行的任务数目:5
线程 pool-1-thread-1结束执行Mon Oct 29 17:29:26 CST 2018获取页数 :4 参数DaoTest [name=li]jian, age=24, phone=13852014259, addr=null, id=null]DaoTest [name=huangjian, age=24, phone=13852014259, addr=null, id=null]
线程池中线程数目:4,队列中等待执行的任务数目:0,已执行的任务数目:6
线程 pool-1-thread-2结束执行Mon Oct 29 17:29:27 CST 2018获取页数 :5 参数DaoTest [name=yangy, age=24, phone=13852014251, addr=null, id=null]DaoTest [name=huangjian, age=24, phone=13852014252, addr=null, id=null]
线程池中线程数目:3,队列中等待执行的任务数目:0,已执行的任务数目:7
线程 pool-1-thread-3结束执行Mon Oct 29 17:29:28 CST 2018获取页数 :1 参数DaoTest [name=lidan, age=26, phone=13852014259, addr=null, id=null]DaoTest [name=yangjian, age=24, phone=13852014256, addr=null, id=null]
线程池中线程数目:3,队列中等待执行的任务数目:0,已执行的任务数目:8
线程 pool-1-thread-4结束执行Mon Oct 29 17:29:33 CST 2018获取页数 :2 参数DaoTest [name=li]jian, age=24, phone=13852014259, addr=null, id=null]DaoTest [name=huangjian, age=24, phone=13852014259, addr=null, id=null]
线程池中线程数目:3,队列中等待执行的任务数目:0,已执行的任务数目:9

我这边用页面开了10个窗口,其中有9个有打印,另外一个被丢弃,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值