多线程队列接收
package org.example.file.mult;
//函数值接口
@FunctionalInterface
public interface FuncationCallback {
void callback(String param);
}
回调接收
package org.example.file.mult;
import java.util.ArrayList;
public class FuncationCallbackImpl {
//函数式 回调参数处理
public FuncationCallbackImpl(ArrayList arrayList, FuncationCallback funcationCallback) {
arrayList.forEach(ele->{
funcationCallback.callback(ele+"456789");
});
}
}
队列业务实现
package org.wangbiao.es.restclient.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.threads.TaskThreadFactory;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class SecurityQueue {
//有界队列,根据实际业务设置即可
public static ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1000);
//静态线程池,一会多线程执行能用到,根据自己的机器性能配置即可
public static Executor executor = new ThreadPoolExecutor(3, 10, 2000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100000), new TaskThreadFactory("测试队列", false, 7));
// 新增用于控制线程等待和唤醒的锁
private static final ReentrantLock lock = new ReentrantLock();
// 基于锁创建的条件对象,用于线程等待和唤醒相关操作
private static final Condition queueNotEmptyCondition = lock.newCondition();
private static final Condition pauseResumeCondition = lock.newCondition();
// 使用AtomicInteger替代volatile int,保证操作原子性
public static AtomicInteger a = new AtomicInteger(0);
public SecurityQueue() {
}
/**
* ,offer方法在队列满时不会阻塞,而是直接返回false。
* 如果业务要求必须保证元素能进入队列(不丢失),
* 可以考虑使用put方法替代,put方法在队列满时会阻塞等待直到有空间可插入元素,
* 这样可以更严格地保证数据完整性,
* 但需要注意阻塞可能带来的线程等待问题以及相应的异常处理(比如被中断的情况)。
*
* @param ele
*/
public void exec(Integer ele) {
queue.offer(ele);
lock.lock(); // 获取锁
try {
queueNotEmptyCondition.signalAll(); // 唤醒所有等待队列非空的线程
} finally {
lock.unlock(); // 释放锁
}
}
//静态内部类,有利于在主程序空值进度
public static class MultTask implements Runnable {
private ArrayBlockingQueue<Integer> arrayBlockingQueue;
//线程-队列构造器 便于每个线程都能冲全局队列取值
public MultTask(ArrayBlockingQueue<Integer> arrayBlockingQueue) {
this.arrayBlockingQueue = arrayBlockingQueue;
}
@Override
public void run() {
lock.lock();
//循环,这里要注意和arrayBlockingQueue1.take()配合使用,避免空悬打满cpu
try {
while (true) {
try {
//当参数等于8时,后面的线程停止取队列的元素进行操作,来达到外界可控的目的
if (a.get() == 8) {
log.info("开始终端了");
pauseResumeCondition.await();
Thread.sleep(50);
log.info("5秒后继续");
a.set(0);
}
// 先判断队列是否为空,如果为空则等待
while (arrayBlockingQueue.isEmpty()) {
queueNotEmptyCondition.await(); // 释放锁并等待,直到被唤醒
}
Integer take = arrayBlockingQueue.take();
String name = Thread.currentThread().getName();
ArrayList arrayList = new ArrayList();
arrayList.add(take);
//队列每次取值后再回调函数里处理后的值
new FuncationCallbackImpl(arrayList, new FuncationCallback() {
@Override
public void callback(String param) {
log.info("返回param:{}", param);
}
});
//TODO 根据自己的业务进行后续处理
log.info(">>>>>>>>>>>>>>>>>>>>>:{},name:{}", take, name);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} finally {
lock.unlock();
}
}
}
// 提供一个方法用于恢复线程执行,在合适的地方调用(比如在主线程中按需求调用)
public static void resumeThreads() {
lock.lock();
try {
a.set(0);
pauseResumeCondition.signalAll();
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
SecurityQueue securityQueue = new SecurityQueue();
for (int i = 0; i < 1000; i++) {
if (i == 8) {
a.set(8);
}
securityQueue.exec(i);
executor.execute(new MultTask(queue));
}
log.info("10s后在运行一次");
Thread.sleep(1000);
resumeThreads();
executor.execute(new MultTask(queue));
}
}
本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaohistory/p/17274823.html

浙公网安备 33010602011771号