多线程队列接收

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));

    }
}

 

posted @ 2023-03-30 23:41  余生请多指教ANT  阅读(20)  评论(0)    收藏  举报