发布时间:2018-05-21作者:laosun阅读(2730)
Java Queue 单线程队列的实现方式,可用于发送消息、记录日志等操作。
直接上代码:
import java.util.Queue; import java.util.concurrent.LinkedBlockingDeque; /** * Java 单线程 Queue 队列 * 顺序执行,先进先出 * @author sun * @date 2018年5月19日 下午12:05:27 */ public class TaskQueue implements Runnable { // protected static final Logger LOG = Logger.getLogger(TaskQueue.class); private static TaskQueue taskQueue = null;// 单例 public Queue<String> queue = new LinkedBlockingDeque<String>(); // public Queue<Map<String, Object>> queue = new LinkedBlockingDeque<Map<String, Object>>();//可以用来处理日志等 /** * 单例获取 * @author sun * @date 2018年5月19日 下午12:09:42 * @return */ public static TaskQueue getInstance() { if (taskQueue == null) { taskQueue = new TaskQueue(); new Thread(taskQueue).start(); } return taskQueue; } /** * 添加任务,并且notify通知 * @author sun * @date 2018年5月19日 下午12:09:30 * @param task */ public void addTask(String task) { queue.add(task); synchronized (queue) { try { //TODO 【正常情况下try块需要删除】 //TODO 为了演示效果,这块延迟500毫秒执行、打印。 System.out.println("线程唤醒"); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } queue.notify();//唤醒 } } public void run() { while (true) { getTask(); } } /** * 监听获取任务 * @author sun * @date 2018年5月19日 下午12:09:22 */ private synchronized void getTask() { String task = null; synchronized (queue) { /** 用于删除第一个头部元素,并且返回第一个头部元素,没有则返回null **/ task = queue.poll(); } if (task == null) { try { synchronized (queue) { try { //TODO 【正常情况下try块需要删除】 //TODO 为了演示效果,这块延迟500毫秒执行、打印。 Thread.sleep(500); System.out.println("线程睡眠,等待被唤醒"); } catch (InterruptedException e) { e.printStackTrace(); } queue.wait();// 继续等待 } } catch (InterruptedException e) { e.printStackTrace(); } } else { doTask(task);//去执行任务 } } /** * 执行获取到的任务 * @author sun * @date 2018年5月19日 下午12:09:59 * @param task */ private void doTask(String task) { System.err.println("任务执行:"+task); } /** * 测试 * @author sun * @date 2018年5月19日 下午12:10:18 * @param args */ public static void main(String[] args) { TaskQueue taskq = TaskQueue.getInstance(); for(int i=0;i<10;i++){ try { Thread.sleep(1000); taskq.addTask("任务编号["+i+"]"); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(3000); taskq.addTask("最后一个任务"); } catch (InterruptedException e) { e.printStackTrace(); } } }
控制台打印:
线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[0] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[1] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[2] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[3] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[4] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[5] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[6] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[7] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[8] 线程睡眠,等待被唤醒 线程唤醒 任务执行:任务编号[9] 线程睡眠,等待被唤醒 线程唤醒 任务执行:最后一个任务 线程睡眠,等待被唤
本实例经过长期运行,发现有问题,更改过后,下边补齐,请谅解
版权属于: 技术客
原文地址: https://www.sunjs.com/article/detail/958c2171273b46eb86a45e145a278895.html
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。