最近一直在研究多线程,走了很多坑,总算把多线程的使用搞清楚了。
阿里的开发文档对多线程的创建强制使用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个有打印,另外一个被丢弃,