Java Queue 线程队列的实现方式

发布时间:2018-05-21作者:laosun阅读(2981)

Java

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]
    线程睡眠,等待被唤醒
    线程唤醒
    任务执行:最后一个任务
    线程睡眠,等待被唤

    本实例经过长期运行,发现有问题,更改过后,下边补齐,请谅解 

0 +1

版权声明

 Java  源码

 请文明留言

0 条评论