Java 线程池RejectedExecutionHandler它是如何工作的

Java 线程池RejectedExecutionHandler它是如何工作的,java,java.util.concurrent,Java,Java.util.concurrent,我的目标是在处理大文件时限制内存使用。 为了做到这一点,我使用了一个线程池实现,这个线程池应该能够使文件加载更多的数据,然后在给定的时间对其进行处理 try (CSVParser parser = new CSVParser(new File("...."))) { ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 5, TimeUnit.MINUTES, new ArrayBlockingQueue<>

我的目标是在处理大文件时限制内存使用。 为了做到这一点,我使用了一个线程池实现,这个线程池应该能够使文件加载更多的数据,然后在给定的时间对其进行处理

try (CSVParser parser = new CSVParser(new File("...."))) {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 5, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1), new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            r.run();
        }
    });

    for (Item item; (item = parser.nextItem()) != null;) {
        executor.submit(new ItemsProcessor(item));
    }

    executor.shutdown();
    executor.awaitTermination(12, TimeUnit.HOURS);
} catch (Exception e) {
    e.printStackTrace();
}
try(CSVParser解析器=新的CSVParser(新文件(“…”)){
ThreadPoolExecutor executor=新的ThreadPoolExecutor(10,10,5,TimeUnit.MINUTES,新的ArrayBlockingQueue(1),新的RejectedExecutionHandler(){
@凌驾
public void rejectedExecution(可运行的r、线程池执行器执行器){
r、 run();
}
});
for(Item;(Item=parser.nextItem())!=null;){
执行人提交(新项目处理人(项目));
}
executor.shutdown();
执行人等待终止(12,时间单位:小时);
}捕获(例外e){
e、 printStackTrace();
}
我的理解是,
RejectedExecutionHandler
rejectedExecution
方法将在主线程上运行,即创建
ThreadPoolExecutor
的线程。是这样吗

被拒绝的任务是否在创建线程池的同一线程上运行


据我所知,这种方法最多只能在内存中加载12项。线程池正在处理的10个线程,一个在线程池队列中,另一个已被拒绝,并在与循环相同的线程上运行(暂停循环)。

RejectExecutionHandler是在第一个执行器停止工作时提供的工具

如果第一个执行器拒绝执行线程,将调用RejectExecutionHandler

    // Create Executor for Normal Execution
    public static ThreadPoolExecutor executor=(ThreadPoolExecutor) Executors.newFixedThreadPool(10);

    // Create Executor for Alternate Execution in case of first Executor shut down
    public static ThreadPoolExecutor alternateExecutor=(ThreadPoolExecutor) Executors.newFixedThreadPool(10);

/ Create Rejected ExecutionHandler Class override rejectedExecution method
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {



    @Override
    public void rejectedExecution(Runnable worker, ThreadPoolExecutor executor) {
        // TODO Auto-generated method stub
        System.out.println(worker.toString()+" is Rejected");

        System.out.println("Retrying to Execute");
        try{
            //Re-executing with alternateExecutor
            RejectedExecutionHandlerExample.alternateExecutor.execute(worker);
            System.out.println(worker.toString()+" Execution Started");
        }
        catch(Exception e)
        {
            System.out.println("Failure to Re-exicute "+e.getMessage());
        }
    }

}



// Register RejectedExecutionHandler in Main Class
RejectedExecutionHandler handler=new MyRejectedExecutionHandler();

executor.setRejectedExecutionHandler(handler);

您是对的,RejectedExecutionHander在主线程中运行

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestRejectedExecution
{
    public static void main( String[] args )
    {
        Runnable r = () -> {
            Thread cur = Thread.currentThread();
            System.out.println( String.format( "in runnable, thread id: %s, name: %s, group name %s",
                                               cur.getId(), cur.getName(), cur.getThreadGroup().getName() ) );
            try
            {
                Thread.sleep( 5000 );
            }
            catch ( InterruptedException e )
            {
                e.printStackTrace();
            }
        };

        Thread cur = Thread.currentThread();
        System.out.println( String.format( "in main, thread id: %s, name: %s, group name %s",
                                           cur.getId(), cur.getName(), cur.getThreadGroup().getName() ) );

        try {
            ThreadPoolExecutor executor = new ThreadPoolExecutor( 1, 1, 0, TimeUnit.MINUTES, new ArrayBlockingQueue<>( 2),
                                                                  ( r1, executor1 ) -> {
                                                                      Thread cur1 = Thread.currentThread();
                                                                      System.out.println( String.format( "in REH, thread id: %s, name: %s, group name %s",
                                                                                                         cur1.getId(), cur1
                                                                                                             .getName(), cur1
                                                                                                             .getThreadGroup().getName() ) );
                                                                  } );

            for (int i=0; i<5; i++ ) {
                executor.submit( r );
            }

            executor.shutdown();
            executor.awaitTermination(1, TimeUnit.MINUTES);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }
}

我知道了
RejectedExecutionHandler
的用途,但我不确定将在哪个线程上调用其
rejectedExecution
方法。我也想知道。我想通过打印RejectedExecutionHandler中的线程信息可以帮助回答这个问题。
in main, thread id: 1, name: main, group name main
in REH, thread id: 1, name: main, group name main
in REH, thread id: 1, name: main, group name main
in runnable, thread id: 11, name: pool-1-thread-1, group name main
in runnable, thread id: 11, name: pool-1-thread-1, group name main
in runnable, thread id: 11, name: pool-1-thread-1, group name main

Process finished with exit code 0