首页 > 其他分享 >多线程中自定义线程池与shiro导致的权限错乱问题解决

多线程中自定义线程池与shiro导致的权限错乱问题解决

时间:2024-07-12 09:12:14浏览次数:6  
标签:自定义 线程 import 多线程 ThreadContext public shiro

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;

import java.util.concurrent.*;

public class ShiroAwareThreadPoolExecutor extends ThreadPoolExecutor {
    public ShiroAwareThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                        TimeUnit unit, BlockingQueue<Runnable> workQueue,
                                        ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    @Override
    public void execute(Runnable command) {
        super.execute(wrap(command, ThreadContext.getSubject()));
    }

    private Runnable wrap(final Runnable task, final Subject subject) {
        return () -> {
            try {
                ThreadContext.bind(subject);
                task.run();
            } finally {
                ThreadContext.unbindSubject();
                ThreadContext.unbindSecurityManager();
            }
        };
    }
}

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 创建自定义线程池
        ExecutorService threadPool = new ShiroAwareThreadPoolExecutor(
                10, 50, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()
        );

        // 提交任务到线程池
        threadPool.submit(() -> {
            System.out.println("执行任务: " + Thread.currentThread().getName());
            // 执行需要 Shiro SecurityManager 的操作
            // 注意:这里需要确保 Shiro 已经正确初始化
            System.out.println("当前用户: " + SecurityUtils.getSubject().getPrincipal());
        });

        // 关闭线程池
        threadPool.shutdown();
    }
}

标签:自定义,线程,import,多线程,ThreadContext,public,shiro
From: https://www.cnblogs.com/jqccan/p/18297498

相关文章

  • 自定义PageHelper分页工具
    今天写了一个需要用到分页查询的需求大概是这样的有一张项目表和一张报警表如下:项目表:报警表:现在我就是要根据这个项目名称,报警类型和报警时间来查询报警列表.项目可以模糊查询,看似是很简单的一个需求,但是我遇到了一个问题我的大概思路就是先用项目名称去项目表......
  • 【线程安全】线程互斥的原理
    文章目录Linux线程互斥线程互斥相关概念互斥量mutex引出线程并发问题引出互斥锁、互斥量互斥量的接口初始化互斥量销毁互斥量互斥量加锁和解锁使用互斥锁抢票可重入和线程安全概念:常见线程不安全的情况常见线程安全的情况常见不可重入的情况常见可重入情况可重入与线......
  • 关于线程池的两种创建方式
    1.第一种方式Executors工具类固定大小线程池:newFixedThreadPool单一线程池:newSingleThreadExecutor可变线程池:newCachedThreadPool调度线程池:newScheduledThreadPool1.1单一线程池该线程池只有一个线程,适用于需要按任务执行线程场景,保证任务的顺序性//创建应该单一线......
  • Java中线程池的最佳实践
    一、使用正确的声明方式线程池必须手动通过ThreadPoolExecutor的构造函数来声明,避免使用Executors类创建线程池,会有OOM风险。Executors创建的线程池对象有以下弊端:FixedThreadPool和SingleThreadExecutor使用的是有界阻塞队列LinkedBlockingQueue,任务队列的默认长度和......
  • Java多线程&并发编程(二)
    一、CyclicBarrier、CountDownLatch、Semaphore的区别CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了这个点,所有线程才重新运行(类似于一个栅栏拦住所有线程直到所有线程到达后在重新执行)CountDownLatch则不是,某线程运行到某个点上之后,......
  • Java异步判断线程池所有任务是否执行完成的方法
    1.使用ExecutorService和CountDownLatch的方法示例在Java中,当我们使用线程池(如ExecutorService)来执行异步任务时,常常需要知道所有任务是否都已经完成。ExecutorService接口提供了几种方式来处理这种情况,但最常用的是shutdown()和awaitTermination()方法的组合,或者使用Future和Com......
  • Linux设备驱动器 之二 线程同步第二篇
    Linux设备驱动器之二线程同步第二篇mutex数据结构LinuxAPIs在Linux驱动器中的应用NXPfreescale系列QSPI驱动器变量定义初始化存取数据semaphore数据结构LinuxAPIs在Linux驱动器中的应用ELAN的Uxxx系列驱动器变量定义初始化同步操作mutex数据结构stru......
  • Qt开发 | Qt创建线程 | Qt并发-QtConcurrent
    文章目录一、Qt创建线程的三种方法二、Qt并发:QtConcurrent介绍三、QtConcurrentrun参数说明四、获取QtConcurrent的返回值五、C++其他线程技术介绍一、Qt创建线程的三种方法  以下是Qt创建线程的三种方法:方法一:派生于QThread派生于QThread,这是Qt创建线程最常用......
  • Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和
    场景存储过程存储过程是一组为了完成特定功能的SQL语句集合。使用存储过程的目的是将常用或复杂的工作预先用SQL语句写好并用一个指定名称存储起来,这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。当以后需要数据库提供与己定义好的存储过程的功能相同的服务时,......
  • Redis中设置增量缓存,减少对数据库的交互查询;启动@Async;异步线程
    //当属于这个分支的报文传入调用processMessage方法if((newJSONObject(dataMessage).optString("documentStatus")).equals("carWeizi_redis_service")){processMessage(dataMessage);}//processMessage中先把增量数据插入数据库,同时缓存redispublic......