`
woxiaoe
  • 浏览: 284461 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java线程学习笔记(十一) DelayQueue的应用

    博客分类:
  • Java
阅读更多

DelayQueue

是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。注意:不能将null元素放置到这种队列中。

 

Delayed

一种混合风格的接口,用来标记那些应该在给定延迟时间之后执行的对象。

此接口的实现必须定义一个 compareTo 方法,该方法提供与此接口的 getDelay 方法一致的排序。

 

下面的代码模拟一个考试的日子,考试时间为120分钟,30分钟后才可交卷,当时间到了,或学生都交完卷了者考试结束。线程的关闭参考Java编程思想中例子,将exec传给Student的一个内部类,通过他来关闭。

package com.woxiaoe.study.thread;

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;

/**
 * 模拟考试,时间为120分钟,学生可以再30分钟后交卷,
 * 当学生都交完了 或 时间到者考试结束
 * @author 小e
 *
 * 2010-4-30 下午11:14:25
 */
class Student implements Runnable,Delayed{
	private String name;
	private long submitTime;//交卷时间
	private long workTime;//考试时间
	public Student() {
		// TODO Auto-generated constructor stub
	}
	public Student(String name, long submitTime) {
		super();
		this.name = name;
		workTime = submitTime;
		//都转为转为ns
		this.submitTime = TimeUnit.NANOSECONDS.convert(submitTime, TimeUnit.MILLISECONDS) + System.nanoTime();
	}

	@Override
	public void run() {
		System.out.println(name + " 交卷,用时" + workTime/100 + "分钟");
	}

	@Override
	public long getDelay(TimeUnit unit) {
		return unit.convert(submitTime - System.nanoTime(), unit.NANOSECONDS);
	}

	@Override
	public int compareTo(Delayed o) {
		Student that = (Student) o;
		return submitTime > that.submitTime?1:(submitTime < that.submitTime ? -1 : 0);
	}
	public static class EndExam extends Student{
		private ExecutorService exec;
		public EndExam(int submitTime,ExecutorService exec) {
			super(null,submitTime);
			this.exec = exec;
		}
		@Override
		public void run() {
			exec.shutdownNow();
		}
	}
	
}
class Teacher implements Runnable{
	private DelayQueue<Student> students;
	private ExecutorService exec;
	
	public Teacher(DelayQueue<Student> students,ExecutorService exec) {
		super();
		this.students = students;
		this.exec = exec;
	}


	@Override
	public void run() {
		try {
			System.out.println("考试开始……");
			while (!Thread.interrupted()) {
				students.take().run();
			}
			System.out.println("考试结束……");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}
	
}
public class Exam {
	static final int STUDENT_SIZE = 45;
	public static void main(String[] args) {
		Random r = new Random();
		DelayQueue<Student> students = new DelayQueue<Student>();
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i = 0; i < STUDENT_SIZE; i++){
			students.put(new Student("学生" + ( i + 1), 3000 + r.nextInt(9000)));
		}
		students.put(new Student.EndExam(12000,exec));//1200为考试结束时间
		exec.execute(new Teacher(students, exec));
		
	}

}

 Output:

考试开始…… 学生19 交卷,用时35分钟 学生16 交卷,用时40分钟 学生7 交卷,用时42分钟 学生14 交卷,用时52分钟 学生15 交卷,用时54分钟 学生1 交卷,用时57分钟 学生11 交卷,用时62分钟 学生2 交卷,用时71分钟 学生13 交卷,用时73分钟 学生3 交卷,用时78分钟 学生20 交卷,用时85分钟 学生17 交卷,用时85分钟 学生18 交卷,用时90分钟 学生6 交卷,用时94分钟 学生9 交卷,用时97分钟 学生8 交卷,用时102分钟 学生12 交卷,用时103分钟 学生5 交卷,用时104分钟 学生10 交卷,用时108分钟 学生4 交卷,用时112分钟 考试结束……

 


6
1
分享到:
评论
1 楼 TenAclock 2012-08-21  
这个例子 做不到“学生都交完” 考试结束,只能做到等到考试时间结束才能结束线程
其实在主线程中只要加上一个变量就可以做到LZ的 做不到“学生都交完” 考试结束。
修改后的代码如下:

public class Exam {
	static final int STUDENT_SIZE = 10;
	public static void main(String[] args) {
		Random r = new Random();
		DelayQueue<Student> students = new DelayQueue<Student>();
		ExecutorService exec = Executors.newCachedThreadPool();
		/***用来记录最后一个交卷的学生的考试时间,然后就可以结束考试了*/
		long shouldEndTime = 0;
		for(int i = 0; i < STUDENT_SIZE; i++){
			long submitTime = 3000 + r.nextInt(9000);
			shouldEndTime = shouldEndTime > submitTime ? shouldEndTime:submitTime;
			students.put(new Student("学生" + i, submitTime));
		}
		/**这一句基本上不用要的,主要是用来确定结束的*/
		shouldEndTime = shouldEndTime > 12000 ? 12000:shouldEndTime;
		students.put(new Student.EndExam((int) shouldEndTime,exec));//1200为考试结束时间
		exec.execute(new Teacher(students));
	}
}


相关推荐

    Java多线程并发开发之DelayQueue使用示例

    "Java多线程并发开发之DelayQueue使用示例" DelayQueue是Java多线程并发开发中的一种常用的数据结构,它是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象。DelayQueue的主要作用是按照对象的延迟时间...

    DelayQueue延迟队列和Redis缓存实现订单自动取消功能

    在Java编程中,DelayQueue是一种特殊的并发队列,它遵循先进先出(FIFO)原则,但具有一个独特的特性:元素只有在其指定的延迟时间过去之后才能被获取和处理。这个特性使得DelayQueue成为实现定时任务和延迟操作的...

    DelayQueue、Redis结合使延迟、定时任务使用源代码

    在提供的源代码`RedisDemo`中,可能包含了如何将`DelayQueue`的概念应用于Redis的实际示例。这个示例可能包括了任务的创建、调度、处理以及相关的异常处理逻辑。通过分析和学习这个源代码,你可以更直观地理解如何将...

    java线程大总结.pdf

    Java线程管理是Java编程中不可或缺的一部分,尤其在并发编程中起到关键作用。在这个大总结中,主要讨论了两种线程同步机制:信号量(Semaphore)和阻塞队列(BlockingQueue),以及Java 6引入的阻塞栈...

    java线程大总结[汇编].pdf

    Java线程管理是多线程编程中的核心概念,它涉及到线程的创建、同步和通信。在Java中,为了高效地处理并发问题,引入了一些高级数据结构,如信号量(Semaphore)和阻塞队列(BlockingQueue)。这些工具在并发编程中起...

    JAVA多线程设计模式详解

    在Java编程领域,多线程是一项至关重要的技术,它允许程序同时执行多个任务,从而提高系统效率和响应性。本书“JAVA多线程设计模式详解”深入探讨了这一主题,旨在帮助开发者理解和掌握如何在Java环境中高效地使用多...

    DelayQueue

    学习视频,可以丰富java知识。能够获得更多的专业技能

    JAVA高并发_学习笔记

    JAVA学习高并发的学习笔记。同步非阻塞式IO:Buffere Channel Selector Concurrent包:Blocking:Queue\Concurrent Hash Map \ExcutorService\lock\原子性 BlockingQueue:ArrayBlockingQueue , DelayQueue , ...

    java中线程队列BlockingQueue的用法

    在Java编程中,`BlockingQueue`(阻塞队列)是一种重要的并发工具,它结合了队列的数据结构和线程同步机制。`BlockingQueue`接口位于`java.util.concurrent`包中,提供了线程安全的数据结构,可以用于实现生产者-...

    Live555 学习笔记

    ### Live555 学习笔记 #### 编译Live555 Live555是一个开源媒体流软件库,广泛应用于实时视频流传输。为了更好地理解和应用Live555,掌握其编译方法至关重要。 - **使用MingW进行编译**: - 在Live555的根目录下...

    Java并发编程相关源码集 包括多任务线程,线程池等.rar

    Java并发编程常见知识点源码集锦,涉及到对象锁,Executors多任务线程框架,线程池等示例,列出一些源码包中包括的内容:  volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小...

    live555学习笔记

    《live555学习笔记》 在深入了解live555之前,我们先了解几个关键的基础类。BasicUsageEnvironment和UsageEnvironment是整个系统的核心组件,它们提供了基础功能和环境支持。UsageEnvironment代表了系统的运行环境...

    DelayQueue的使用以及注意事项

    DelayQueue的使用以及注意事项,这里需要由BlockingQueue的基本知识,一般的Queue的使用方法poll(),take(),drainTo()和offer(),put()这些应该懂。

    JDK自带的延迟队列-DelayQueue

    在Java的并发编程中,`DelayQueue`是一个非常特殊的队列,它属于并发包`java.util.concurrent`的一部分。`DelayQueue`是一个基于优先级队列(PriorityQueue)实现的无界阻塞队列,它的主要特性是元素只有在达到指定...

    java利用delayedQueue实现本地的延迟队列

    DelayedQueue 的实现是基于 Java 中的阻塞队列的接口 BlockingQueue, DelayQueue 是其的一种实现。 DelayQueue 提供了一个无界的阻塞队列,用于存放实现了 Delayed 接口的对象。 DelayQueue 能够保证队列中的对象...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段28讲、线程生产者消费者的综合实战结合Java8语法.mp4 │ 高并发编程第一阶段29讲、如何实现一个自己的显式锁Lock精讲上.mp4 │ 高并发编程第一阶段30讲、如何实现一个自己的显式锁Lock精讲...

    java concurrent 精简源码

    这个“java concurrent 精简源码”资源很可能会包含上述概念的实际应用示例,通过学习和分析这些代码,你可以深入理解Java并发编程的精髓,并能更好地应用于实际项目中。在研究时,建议结合Java官方文档和相关的书籍...

Global site tag (gtag.js) - Google Analytics