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 {//用户idprivate 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);}@Overridepublic 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;}@Overridepublic 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));}
}
可以看到,在用户等待的时候,会显示需要等待多少秒之后 才能抢到