有界阻塞队列,内部使用数组存储元素,有2个常用构造方法:
capacity表示容量大小,默认内部采用非公平锁
public ArrayBlockingQueue(int capacity)
capacity:容量大小,fair:内部是否是使用公平锁
public ArrayBlockingQueue(int capacity, boolean fair)
1.demo
public class Demo { //推送队列 static ArrayBlockingQueue<String> pushQueue = new ArrayBlockingQueue<String>(10000); static { //启动一个线程做真实推送 new Thread(() -> { while (true) { String msg; try { long starTime = System.currentTimeMillis(); //获取一条推送消息,此方法会进行阻塞,直到返回结果 msg = pushQueue.take(); long endTime = System.currentTimeMillis(); //模拟推送耗时 TimeUnit.MILLISECONDS.sleep(500); System.out.println(String.format("[%s,%s,take耗时:%s],%s,发送消息:%s", starTime, endTime, (endTime - starTime), Thread.currentThread().getName(), msg)); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } //推送消息,需要发送推送消息的调用该方法,会将推送信息先加入推送队列 public static void pushMsg(String msg) throws InterruptedException { pushQueue.put(msg); } public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 5; i++) { String msg = "消息内容"; //模拟耗时 TimeUnit.SECONDS.sleep(i); Demo1.pushMsg(msg); } } } 创建ArrayBlockingQueue时候需要制定容量大小,调用pushQueue.put将推送信息放入队列中,如果队列已 满,此方法会阻塞。代码中在静态块中启动了一个线程,调用pushQueue.take();从队列中获取待推送的信息进行推送处理。 注意:ArrayBlockingQueue如果队列容量设置的太小,消费者发送的太快,消费者消费的太慢的情况下,会导致队列空间满, 调用put方法会导致发送者线程阻塞,所以注意设置合理的大小,协调好消费者的速度。
2.
package com...BlockingQueue; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import wfc.service.database.RecordSet; import wfc.service.database.SQL; import java.util.concurrent.*; @Component @EnableScheduling//可以在启动类上注解也可以在当前文件 public class BlockingQueues { private static ExecutorService service = Executors.newFixedThreadPool(10); private static BlockingQueue<String> queue = new ArrayBlockingQueue<>(100); // private static RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();拒绝策略 // private static ExecutorService executorService = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, queue, handler); @Scheduled(cron = "0 0/1 * * * ?")//1分钟 public void query(){ doSting(); } private static void doSting(){ new Thread(new Runnable() { boolean flag = true; @Override public void run() { System.out.println("开始扫描未推送的办件到BlockingQueue...."); String type = "0"; String insertSql = "select * from DANGAN_FJ where TYPE = ? "; Object[] insertObject = new Object[] {type}; RecordSet rs = SQL.execute(insertSql,insertObject); while (rs.next()){ String ST_FJ_ID = rs.getString("ST_FJ_ID"); try { queue.put(ST_FJ_ID); } catch (InterruptedException e) { System.out.println("放入队列出异常...:"+e); e.printStackTrace(); } } System.out.println("BlockingQueue队列里的办件--->:"+queue); while (flag) { service.execute(new Runnable() { @Override public void run() { try { String ST_FJ_ID = queue.take(); String updateSql = "update dangan_fj set type =-1 where st_fj_id = ? "; Object[] updateObject = new Object[]{ST_FJ_ID}; RecordSet updateRs = SQL.execute(updateSql, updateObject); int number = updateRs.TOTAL_RECORD_COUNT; //影响行数 System.out.println("办件过期更改影响行数: " + number + " 办件编号为:" + ST_FJ_ID+" 处理线程:"+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } }); if(queue.isEmpty()){ flag =false; } } } },"").start(); } }