package com.example.demo1.service.impl;
import lombok.Data;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
@Data
public class User {
//用户id
private Integer id;
//姓名
private String name;
//插入的时间
private LocalDateTime date;
}
package com.example.demo1.service.impl;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 排队任务
* 5秒内随机进来1个用户
*/
public class PaiDuiTask implements Runnable{
private AtomicInteger atomicInteger;
private BlockingQueue<User> blockingQueue;
public PaiDuiTask(BlockingQueue<User> blockingQueue){
this.blockingQueue=blockingQueue;
atomicInteger=new AtomicInteger(0);
}
@Override
public void run() {
while (true){
//设置每个用户的随机进来的时间
int next=new Random().nextInt(5);
try {
Thread.sleep(1000*next);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
User user=new User();
//用户id 自增
user.setId(atomicInteger.getAndIncrement());
user.setName("用户"+user.getId());
//当前时间
user.setDate(LocalDateTime.now());
long miao=0;
if(blockingQueue.peek()!=null){
//获取队列中第一个元素的时间
LocalDateTime oneTime=blockingQueue.peek().getDate();
//当前时间减去队列中的时间 就是需要等待的时间
miao = ChronoUnit.SECONDS.between(oneTime, user.getDate());
}
System.out.println(user.getName()+"进入排队中,需要等待"+miao+"秒");
//把用户加入到队列中
try {
blockingQueue.put(user);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
package com.example.demo1.service.impl;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
/**
* 抢手机的任务
* 从队列中取出数据
*/
public class QiangTask implements Runnable{
private BlockingQueue<User> blockingQueue;
public QiangTask(BlockingQueue<User> blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run() {
while (true){
//从队列中取出用户信息
User user = null;
try {
//如果队列是空的 就会一直阻塞
user = blockingQueue.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(user.getName()+"正在处理");
try {
//假设每个用户处理间隔 随机5秒内
int next=new Random().nextInt(5);
Thread.sleep(1000*next);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(user.getName()+"处理完成");
}
}
}
测试类 定义线程池 把2个任务 放入线程池去执行
一边模拟用户进来,一边模拟用户进行抢购
package com.example.demo1.service.impl;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test {
//自定义线程池
public static ThreadPoolExecutor threadPoolExecutor(){
//核心线程数
int corePoolSize=20;
//最大线程数
int maximumPoolSize=100;
//存活时间
long keepAliveTime=60;
//存活时间单位
TimeUnit unit=TimeUnit.SECONDS;
//阻塞队列
BlockingQueue<Runnable> workQueu=new LinkedBlockingQueue<>(100);
return new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueu);
}
public static void main(String[] args) {
//获取线程池
ThreadPoolExecutor executor=threadPoolExecutor();
//链表阻塞队列
BlockingQueue<User> blockingQueue=new LinkedBlockingQueue<>(100);
//执行排队线程
executor.execute(new PaiDuiTask(blockingQueue));
//执行消费任务 抢购手机
executor.execute(new QiangTask(blockingQueue));
}
}
可以看到,在用户等待的时候,会显示需要等待多少秒之后 才能抢到