java DelayQueue 延期队列 21.7.3 -------thinking java 4

package org.rui.thread.newc;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 延期队列 优先级队列的一种变体
 *
 * @author lenovo
 *
 */

class DelayedTask implements Runnable, Delayed
{

	private static int counter = 0;
	private final int id = counter++;// id 从0++
	private final int delta;// 多少毫秒停止
	private final long trigger;// 纳秒停止

	// 保存了任务被创建的顺序
	protected static List<DelayedTask> sequence = new ArrayList<DelayedTask>();

	public DelayedTask(int delayInMilliseconds)
	{
		delta = delayInMilliseconds;
		trigger = System.nanoTime()
				+ TimeUnit.NANOSECONDS.convert(delta, TimeUnit.MILLISECONDS);

		sequence.add(this);
	}

	@Override
	public void run()
	{
		System.out.println(this + " run");
	}

	public String toString()
	{
		// 1个id对应一项任务 会安顺序来执行任务
		return String.format("[%1$-4d]", delta) + " Task " + id;
	}

	public String summary()
	{
		return "(" + id + ":" + delta + ")";
	}

	// 排序触发
	@Override
	public int compareTo(Delayed o)
	{
		DelayedTask that = (DelayedTask) o;
		if (trigger < that.trigger)
			return -1;
		if (trigger > that.trigger)
			return 1;
		return 0;
	}

	/**
	 * 告知延迟到期有多长时间 ,或者延迟在多长时间之前已经到期
	 */
	@Override
	public long getDelay(TimeUnit unit)
	{
		// 对象到期时间 -现在时间 =执行时间
		return unit.convert(trigger - System.nanoTime(), TimeUnit.NANOSECONDS);
	}

	// 关闭所有事物的途径 具体做剥去 是将其放置为队列的最后一个元素。
	public static class EndSentinel extends DelayedTask
	{

		private ExecutorService exec;

		public EndSentinel(int delayInMilliseconds, ExecutorService c)
		{
			super(delayInMilliseconds);
			exec = c;
		}

		@Override
		public void run()
		{
			for (DelayedTask pt : sequence)
			{
				System.out.print(pt.summary() + " ");
			}
			System.out.println();
			System.out.println(this + "  calling shutdownNow");
			exec.shutdownNow();
		}
	}
}

// 自身是一个任务
class DelayedTaskConsumer implements Runnable
{
	private DelayQueue<DelayedTask> q;

	public DelayedTaskConsumer(DelayQueue<DelayedTask> q)
	{
		this.q = q;
	}

	@Override
	public void run()
	{
		try
		{
			while (!Thread.interrupted())
			{
				q.take().run();// run task with the current thread 与当前线程运行的任务
			}
		} catch (InterruptedException e)
		{
			System.out.println("可接受的方式退出=");
			// 可接受的方式退出
		}
		System.out.println("finished delayedTaskConsumer");
	}
}

public class DelayQueueDemo
{
	public static void main(String[] args)
	{
		Random rand = new Random(47);
		ExecutorService exec = Executors.newCachedThreadPool();
		DelayQueue<DelayedTask> queue = new DelayQueue<DelayedTask>();
		// fill with tasks that have random delays:充满随机延迟的任务
		for (int i = 0; i < 20; i++)
		{
			queue.put(new DelayedTask(rand.nextInt(5000)));
		}
		// 设置停止点
		queue.add(new DelayedTask.EndSentinel(5000, exec));
		exec.execute(new DelayedTaskConsumer(queue));

	}
}
/** output:
[128 ] Task 11 run
[200 ] Task 7 run
[429 ] Task 5 run
[520 ] Task 18 run
[555 ] Task 1 run
[961 ] Task 4 run
[998 ] Task 16 run
[1207] Task 9 run
[1693] Task 2 run
[1809] Task 14 run
[1861] Task 3 run
[2278] Task 15 run
[3288] Task 10 run
[3551] Task 12 run
[4258] Task 0 run
[4258] Task 19 run
[4522] Task 8 run
[4589] Task 13 run
[4861] Task 17 run
[4868] Task 6 run
(0:4258) (1:555) (2:1693) (3:1861) (4:961) (5:429) (6:4868) (7:200) (8:4522) (9:1207) (10:3288) (11:128) (12:3551) (13:4589) (14:1809) (15:2278) (16:998) (17:4861) (18:520) (19:4258) (20:5000)
[5000] Task 20  calling shutdownNow
finished delayedTaskConsumer
*/

时间: 2024-10-31 14:34:20

java DelayQueue 延期队列 21.7.3 -------thinking java 4的相关文章

java中使用队列:java.util.Queue (转)

Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Queue接 口.Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用.BlockingQueue 继承了Queue接口. 队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就

Java多线程 阻塞队列和并发集合

转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的线程安全的集合类,通过下面的学习,您需要掌握这些集合的特点是什么,底层实现如何.在何时使用等问题. 3.1 BlockingQueue接口 java阻塞队列应用于生产者消费者模式.消息传递.并行任务执行和相关并发设计的大多数常见使用上下文. BlockingQueue在Queue接口基础上提供了额外

Java Swing界面编程(21)---事件处理:窗体事件

Splay树的插入操作,只需要处理好插入节点的孩子节点就可以了,最重要的是不要破坏了BST的基本规则. 因为高度并不是Splay树的首要因素,所以插入的时候也是使用splay操作,然后在根节点插入. 参考:http://www.geeksforgeeks.org/splay-tree-set-2-insert-delete/ 对比一下使用插入创建的树和手工创建数的区别,先序遍历的结果: #pragma once #include<stdio.h> #include <stdlib.h&g

java中String的21种用法

(构造函数必须new出来) * public String (char[] vaue)                         将一个字符数组变成字符串(构造函数) * public String (char[] vaue,int offset,int count)    将制定范围内的字符数组变为字符串(构造函数) * public String (byte[],bytes)                        将一个byte数组变为字符串(构造函数) * public St

使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点?

我感觉很多项目使用java或者c的多线程库+线程安全的queue数据结构基本上可以实现goroutine+channel开发能达到的需求,所以请问一下为什么说golang更适合并发服务端的开发呢?使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点? 使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点? >> golang 这个答案描述的挺清楚的:http://www.goodpm.net/postreply

java实现链队列

java实现链队列的类代码: package linkqueue; public class LinkQueue { class Element { Object elem; Element next; } private Element front; private Element rear; private Element header = null; /** * 初始化队列 * */ void initQueue() { header = new Element(); front = ne

两个栈实现一个队列以及两个队列实现一个栈(Java)

两个栈实现一个队列 import java.util.Stack; public class Demo07 { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int node) { stack1.push(node); } public int pop() { if(stack2.size

Java调用MQ队列

IBM MQ 6.0中设置两个队列,(远程队列.通道之类都不设置). 队列管理器是XIR_QM_1502 队列名称是ESBREQ IP地址是10.23.117.134(远程的一台电脑,跟我的电脑不在一个局域网内) 端口1414 CCSID 1208 MQ配置可以参考这个,有配图http://wenku.baidu.com/view/06d108d0360cba1aa811daa3.html 程序如下,发送线程两个,接收线程一个.接收完毕后就结束. [java] view plaincopy /*

设计模式之第21章-状态模式(Java实现)

设计模式之第21章-状态模式(Java实现) “what are you 干啥了?怎么这么萎靡不振?”“昨晚又是补新番,又是补小笼包,睡得有点晚啊.话说杨过的那个雕兄真是太好了,每天给找蛇胆,又陪练武功的,想不无敌都难啊,还有那个blablabla”(作者已被拖走).咳咳,今天那个状态哥哥马不停蹄的赶过来,下面闪亮登场. 状态模式之自我介绍 今天不在状态,可能是由于宇宙差的原因,好了,先说下定义:Allow an object to alter its behavior when its int