SynchronousQueue:一个不存储元素的阻塞队列。每一个 put 操作必须等待一个 take 操作,否则不能继续添加元素。内部没有容器,一个生产线程,当它生产产品(即put的时候),如果当前没有人想要消费产品(即当前没有线程执行take),此生产线程必须阻塞,等待一个消费线程调用take操作,take操作将会唤醒该生产线程,同时消费线程会获取生产线程的产品(即数据传递),这样的一个过程称为一次配对过程(当然也可以先take后put,原理是一样的)。
package com.neo.study001.redio13;
import java.util.concurrent.SynchronousQueue;
/**
* @author liyy
* @date 2020/4/26 23:56
*/
public class UseSynchronousQueue {
public static void main(String[] args) throws Exception{
final SynchronousQueue<Integer> queue = new SynchronousQueue<Integer>();
//queue.add(1); SynchronousQueue使用add()方法会抛java.lang.Exception: Queue full异常
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("put thread start");
try {
queue.put(1);
} catch (InterruptedException e) {
}
System.out.println("put thread end");
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("take thread start");
try {
System.out.println("take from putThread: " + queue.take());
} catch (InterruptedException e) {
}
System.out.println("take thread end");
}
},"t2");
t1.start();
Thread.sleep(1000);
t2.start();
}
}
PriorityBlockingQueue:无界优先级队列PriorityBlockingQueue 内部使用堆算法保证每次出队都是优先级最高的元素
优先级队列插入的元素依据元素的Comparable, 不允许插入一个不可比较的元素。
package com.neo.study001.redio13;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
/**
* @author liyy
* @date 2020/4/26 23:56
* 会在调用take方法时,实现一次优先级排序
*/
public class UsePriorityBlockingQueue {
public static void main(String[] args) throws Exception{
final PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<Task>();
for (int i = 0; i <10; i++) {
int id=new Random().nextInt(10);
queue.add(new Task(id,"name_"+id));
}
System.out.println(queue);
System.out.println(queue.size());
System.out.println(queue.take());
System.out.println(queue);
}
static class Task implements Comparable<Task> {
private int id;
private String name;
public Task(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Task o) {
return this.id>o.id?1:(this.id<o.id?-1:0);
}
@Override
public String toString() {
return "Task{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
}
DelayQueue:延迟队列提供了在指定时间才能获取队列元素的功能,队列头元素是最接近过期的元素。没有过期元素的话,使用poll()方法会返回null值,超时判定是通过getDelay(TimeUnit.NANOSECONDS)方法的返回值小于等于0来判断。延时队列不能存放空元素,延时队列实现了Iterator接口,但iterator()遍历顺序不保证是元素的实际存放顺序.
package com.neo.study001.redio13;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* @author liyy
* @date 2020/4/27 23:23
* 模拟网吧营业
*/
public class UseDelayQueue {
public static void main(String[] args) {
WangBa wangBa = new WangBa();
Thread t = new Thread(wangBa);
t.start();
wangBa.shangji("zhangsan", "1111", 2);
wangBa.shangji("lisi", "1111", 5);
wangBa.shangji("wangwu", "1111", 10);
}
static class WangBa implements Runnable {
private DelayQueue<Wangming> queue = new DelayQueue<Wangming>();
public boolean yinye = true;
public void shangji(String name, String id, long money) {
Wangming wangming = new Wangming(name, id, money * 1000 + System.currentTimeMillis());
System.out.println("网民:" + name + " ,id:" + id + " ,缴费:" + money + "元,开始上机");
this.queue.add(wangming);
}
public void xiaji(Wangming w) {
System.out.println("网民:" + w.getName() + "下机时间到");
}
@Override
public void run() {
while (yinye) {
Wangming w = null;
try {
w = queue.take();
xiaji(w);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Wangming implements Delayed {
private String name;
private String id;
private long endTime;
private TimeUnit timeUnit = TimeUnit.SECONDS;
public Wangming(String name, String id, long endTime) {
this.name = name;
this.id = id;
this.endTime = endTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public int compareTo(Delayed o) {
Wangming w = (Wangming) o;
return this.getDelay(this.timeUnit) - w.getDelay(this.timeUnit) > 0 ? 1 : 0;
}
@Override
public long getDelay(TimeUnit unit) {
return endTime - System.currentTimeMillis();
}
}
}