introdução
ThreadPoolExcutor
A JDK
built-in thread pool, mas também muitas vezes usamos o método para criar quando você cria um pool de threads. Tópico piscina um pouco de compreensão dos alunos sabe, o pool de threads é uma piscina típica do projeto cache. JDK
Vem com quatro tarefas negar a política, mas às vezes nós não pode satisfazer as necessidades reais de negócios, portanto, neste caso é preciso personalizar a política de se recusar a lidar com o pool de threads tarefa rejeitada.
- Segmento de pool vem negar política introduzida
- Como negar personaliza política
Em primeiro lugar, vem a política segmento pool de rejeição introduzido
JDK vem com a estratégia de negação pool de threads tem as seguintes quatro categorias:
1, DiscardPolicy: tarefa de descarte silenciosamente não pode ser processado sem qualquer tratamento;
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
2, DiscardOldestPolicy : descartar a tarefa mais antiga na fila, tente enviar o trabalho atual de novo;
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
3, AbortPolicy : tiro directo uma excepção que impede que o sistema está a funcionar correctamente;
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
4, CallerRunsPolicy : será dividido para o segmento chamado para executar a tarefa, execute a tarefa a ser descartada, então, fazer tarefa não é realmente descarte, mas o desempenho da linha é provável que apresente um declínio acentuado
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
Podemos ver que as três primeiras estratégias são devoluções a tarefa original. No entanto, em alguns cenários de negócios, não podemos descartar a tarefa brutal. A quarta estratégia recusou é lidar com tarefa descartado, iniciando um thread do pool, mas o problema é que mesmo o ocioso pool de threads, não vai executar tarefas descartado, mas espera para o segmento principal chama o pool de threads para executar a tarefa, até o fim da missão.
Em segundo lugar, vem a política segmento pool de rejeição introduzido
Na definição do pool de threads, podemos ver que existe uma política unificada de se recusar a implementar a interface, como segue:
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
Podemos definir estratégia de processamento de acordo com os seus próprios cenários de negócios de acordo com suas necessidades de negócios. Podemos olhar para alguns dos mainstream quadro é a forma de definir a sua própria estratégia de auto-processamento.
1, Netty fios na política de rejeição piscina
private static final class NewThreadRunsPolicy implements RejectedExecutionHandler {
NewThreadRunsPolicy() {
super();
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
final Thread t = new Thread(r, "Temporary task executor");
t.start();
} catch (Throwable e) {
throw new RejectedExecutionException(
"Failed to start a new thread", e);
}
}
}
Fonte pode ser visto acima, Netty
a tarefa de manipulação não é descartado, e essa idéia CallerRunsPolicy
vantagens semelhantes. Em apenas Netty
a custom frame rejeitar estratégia é para completar a tarefa de fio descartados através do novo trabalho, mas chegamos a olhar para ele em um segmento é criado, há condições de restrição, desde que os recursos permitem continuar a criar novos thread para o processamento.
2, Dubbo fios na política de rejeição piscina
public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
protected static final Logger logger = LoggerFactory.getLogger(AbortPolicyWithReport.class);
private final String threadName;
private final URL url;
private static volatile long lastPrintTime = 0;
private static Semaphore guard = new Semaphore(1);
public AbortPolicyWithReport(String threadName, URL url) {
this.threadName = threadName;
this.url = url;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
String msg = String.format("Thread pool is EXHAUSTED!" +
" Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: %d)," +
" Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!",
threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(), e.getLargestPoolSize(),
e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(),
url.getProtocol(), url.getIp(), url.getPort());
logger.warn(msg);
dumpJStack();
throw new RejectedExecutionException(msg);
}
private void dumpJStack() {
//省略实现
}
}
Dubbo
recusou costume estratégia, imprimir as informações atuais da pilha de encadeamentos de saída log e executar JDK
a política padrão deny.