如何写一个高效稳定的缓存队列

   阅读
怎么写一个高效稳定的缓存队列?
我写了一个,大家给点意见

队列和executor
public class SyncQueue {

public static final ExecutorService executorService = Executors.newFixedThreadPool(10);

public static final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(200);

public static final Deque<String> dq = new LinkedBlockingDeque<String>(10);
// public static boolean addjob(String jsonData) {
// return queue.offer(jsonData);
// }
}


servlet,接受请求

public class Clean extends HttpServlet {
private static final long serialVersionUID = 1L;

private static Logger log = Logger.getLogger(Clean.class);

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionIOException {

String jsonData = request.getParameter("json");

if (jsonData != null && !jsonData.equals("")) {

if (SyncQueue.queue.offer(jsonData)) {//添加到缓存队列
SyncQueue.executorService.execute(new DealThread());//调用线程执行
log.info("ok," + jsonData);
response.sendError(HttpServletResponse.SC_OK);
} else {
log.info("full   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + jsonData);
response.sendError(HttpServletResponse.SC_TEMPORARY_REDIRECT);
}
} else {
log.info("wrong param" + jsonData);
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);
}

}


处理线程
public class DealThread implements Runnable {

private static Logger log = Logger.getLogger(DealThread.class);

private String name = "";

public DealThread() {
}

public DealThread(String name) {
this.name = name;
}

@Override
public void run() {

String json = SyncQueue.queue.poll();
if (json != null) {
log.info("josn:" + json);
long start = System.currentTimeMillis();
Connection conn = DBPool.getInstance().getConnection("live");
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement("select * from channel where id=?");
pstmt.setInt(1, Integer.parseInt(json));
rs = pstmt.executeQuery();
while (rs.next()) {
log.info("thread," + Thread.currentThread().getName() + ":" + rs.getString("channelName"));
}
Thread.sleep(new Random().nextInt(4000));//for test模拟大任务
} catch (SQLException e) {
retry(json);
log.error(" sql exception ;", e);
} catch (InterruptedException e) {
retry(json);
log.error(" interrupted; ", e);
} finally {
DBPool.close(pstmt, rs, conn);
}
long exeTime = System.currentTimeMillis() - start;
log.info("thread," + Thread.currentThread().getName() + ":" + exeTime + "ms");
}
}

private void retry(String json) {
Connection conn = DBPool.getInstance().getConnection("live");
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement("select * from channel where id=?");
pstmt.setInt(1, Integer.parseInt(json));
rs = pstmt.executeQuery();
while (rs.next()) {
log.info("thread," + Thread.currentThread().getName() + ":" + rs.getString("channelName"));
}
Thread.sleep(new Random().nextInt(4000));//for test模拟大任务
} catch (SQLException e) {
log.error(" sql exception ;", e);
} catch (InterruptedException e) {
log.error(" interrupted; ", e);
} finally {
DBPool.close(pstmt, rs, conn);
}
}

}

------解决方案--------------------
线程池同样也支持把超出的任务放进队列的操作,为什么lz要自己写一个队列先入列再起线程,感觉和直接用线程池没有区别,反而复杂了
------解决方案--------------------
引用:
Quote: 引用:

感觉直接使用线程池就好了,没看出来这里使用队列的意义在哪?


直接用线程池的话,

如果线程池处理不过来,怎么通知客户端,说已经满了处理不过来了?


ThreadPoolExecutor 类不是可以使用相关的 RejectedExecutionHandler 接口么?默认的是 AbortPolicy 实现,即抛出异常。
阅读