代码之家  ›  专栏  ›  技术社区  ›  IdiotDrake

执行新Runnable时丢失ApplicationContext

  •  0
  • IdiotDrake  · 技术社区  · 6 年前

    我知道我对这个春天的事还不熟悉,但我一整天都在做这个。我不太喜欢问问题,但也许我会有个主意。

    所以我的问题是:

    @Component
    public class FifoComponent {
    public static ExecutorService executors = Executors.newSingleThreadExecutor();
    private static Lock lock = new ReentrantLock(true);
    
    public static void executeNewTestJob(int i) {
        lock.lock();
        OrderAllocationTestJob job = new OrderAllocationTestJob(i);
        executors.execute(job);
        lock.unlock();
    }
    }
    

    Runnable component-note appdateutils有一个方法,可以调用在我典型的tomcat环境中运行良好的组件

    @Component
    public class OrderAllocationTestJob implements Runnable {
    int i;
    
    public OrderAllocationTestJob(int i) {
        this.i = i;
    }
    
    @Override
    public void run() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Asynchronous task " + i);
        System.out.println(AppDateUtils.getCurrentTimeStamp());
    }
    }
    

    调用struts2操作(测试)我知道我可以调用appdateutils.gettime文件方法来自

        for (int i = 0; i < 50; i++) {
            FifoComponent.executeNewTestJob(i);
        }
    

    Exception in thread "pool-15-thread-50" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dateTimestampDao': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    
    4 回复  |  直到 6 年前
        1
  •  0
  •   Gilliard Macedo    6 年前

    “我相信有更好的方法”

    基于此,您需要在调用另一个线程之前创建/查找所有请求和会话范围的组件。实际上,请求注入是线程本地的,不能在您的场景中工作。

        2
  •  0
  •   Amin Chokan    6 年前

    我想如果你离开

    Thread.sleep(100);
    

    job.sleep(100);

    在FifoComponent将解决您的问题

        3
  •  0
  •   IdiotDrake    6 年前

    我通过为我的runnable扩展ConcurrentLinkedQueue并将它们保存在我在ServletContextListener的initialize方法中实例化的管理器中来解决这个问题。通过重写ConcurrentLinkedQueue的offer()方法来持续轮询,直到队列为空为止,我能够同步处理可运行文件。

    我仍然希望ExecutorService从我的Tomcat容器中执行,但是在请求的范围之外,但是除非有人能回答这个问题,否则我现在就不得不离开它

        4
  •  0
  •   Kumar Panchal    6 年前

    @组成部分 公共类AsynchronousThread扩展线程{

    public static final Logger LOGGER = LoggerFactory
            .getLogger(AsynchronousThread.class);
    
    @Autowired
    private Writer writer;
    
    
    private BlockingQueue<IndexContextDTO> blockingQueue = new LinkedBlockingQueue<IndexContextDTO>(
            500);
    
    /**
     * 
     */
    public AsynchronousThread() {
        super("AsynchronousThread");
    }
    
    
    @PostConstruct
    public void init() {
        Integer internalQueueSize = 100;
        this.blockingQueue = new LinkedBlockingQueue<>(internalQueueSize);
        this.start();
    }
    
    
    @Override
    public void run() {
    
        while (true) {
            // Do stuff
        }
    }
    
    
    public void putInQueue(IndexContextDTO message) {
        try {
            this.blockingQueue.put(message);
        } catch (InterruptedException interruptedException) {
            // This exception will be thrown in very rare case.
            LOGGER.error("An error while putting message in the queue. "
                    + message, interruptedException);
        }
    }
    

    }