newSingleThreadExexcutor: Thread-Pool mit einzelner Thread-Nummer (Anzahl der Kern-Threads = maximale Anzahl von Threads = 1)
newFixedThreadPool: Thread-Pool mit fester Anzahl von Threads (Anzahl der Kern-Threads = maximale Anzahl von Threads = benutzerdefiniert )
newCacheThreadPool: Cachebarer Thread-Pool (Anzahl der Kernthreads = 0, maximale Anzahl der Threads = Integer.MAX_VALUE)
newScheduledThreadPool: Thread-Pool, der geplante oder periodische Aufgaben unterstützt (Anzahl der Kernthreads = benutzerdefiniert, maximal Anzahl der Threads = Ganzzahl .MAX_VALUE)
Die oben genannten vier Thread-Pool-Klassen erben alle ThreadPoolExecutor und geben beim Erstellen direkt neue ThreadPoolExecutor (Parameter) zurück. Der Unterschied zwischen ihnen besteht darin, dass die Parameter im definierten ThreadPoolExecutor (Parameter) unterschiedlich sind und ThreadPoolExecutor die ExecutorService-Schnittstellenklasse erbt
NeufixedThreadpoolEs ist ersichtlich, dass die Essenz von FixedExecutorService ThreadPoolExecutor ist, sodass FixedExecutorService zu ThreadPoolExecutor gezwungen werden kann, SingleExecutorService jedoch nichts mit ThreadPoolExecutor zu tun hat Daher schlägt die erzwungene Übertragung fehl, sodass newSingleThreadExecutor() Nach der Erstellung kann es nicht mehr geändert werden. Ändern Sie die Thread-Pool-Parameter, um wirklich einen einzelnen Thread zu erreichen.
Nachteile: Die Blockierungswarteschlange für verknüpfte Listen von LinkBlockQueue wird verwendet. Wenn die Akkumulationsgeschwindigkeit von Aufgaben höher ist als die Verarbeitungsgeschwindigkeit, kann es leicht zu einer Akkumulation von Aufgaben und einem OOM-Speicherüberlauf kommen.
newCacheThreadPool
ScheduledThreadPoolDefinition: ExecutorService executorService=Executors.Nachteile: SynchronousQueue ist eine Implementierung von BlockingQueue. Es handelt sich auch um eine Warteschlange, da die maximale Anzahl von Threads Integer.MAX_VALUE beträgt. Wenn also zu viele Threads vorhanden sind, kann es leicht zu einem OOM-Speicherüberlauf kommen
源码: public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { //ScheduledThreadPoolExecutor继承ThreadPoolExecutor return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { //ScheduledThreadPoolExecutor继承ThreadPoolExecutor,故super()会调用ThreadPoolExecutor的构造函数初始化并返回一个ThreadPoolExecutor,而ThreadPoolExecutor使实现ExecutorService接口的 //最终ScheduledThreadPoolExecutor也和上面几种线程池一样返回的是ExecutorService接口的实现类ThreadPoolExecutor super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
Was sind die wichtigen Parameter des Thread-Pools? Die Konstruktionsmethode von
ThreadPoolExecutor lautet wie folgt:keepAliveTime bezieht sich darauf, wie lange diese Nicht-Kern-Threads ohne Arbeit auf Leerlaufzeit warten, wenn die aktuelle Anzahl von Threads zwischen [Anzahl der Kern-Threads, maximal Anzahl der Threads], Verlassen Sie einfach den Thread-Pool;
Die Größe der Warteschlange hat nichts mit der maximalen Anzahl von Threads zu tun. Thread-Erstellungspriorität = Kern-Threads > Blockierungswarteschlange > erweiterte Threads (wenn die aktuelle Anzahl von Kern-Threads sind kleiner als die maximale Anzahl von Threads, um Threads zu erweitern)
Wenn die Anzahl der Kern-Threads 5 beträgt, beträgt die Länge der Warteschlange 3 und die maximale Anzahl von Threads beträgt 10: Wenn die Anzahl der Threads weiterhin anhält Erhöhen Sie, erstellen Sie zuerst 5 Kernthreads und werfen Sie dann die Threads hinein. Warten Sie, bis die Warteschlange verloren geht, und warten Sie, bis die Warteschlange voll ist (3 Threads). Zu diesem Zeitpunkt wird die maximale Anzahl von Threads verglichen (nur wenn das Maximum erreicht ist). Die Anzahl der Threads, die auf den Verlust der Warteschlange warten müssen, kann angezeigt werden. Sie können weiterhin 2 Threads erstellen (5+3+2). Wenn die Anzahl der Threads die maximale Anzahl von Threads überschreitet, wird die Ablehnungsrichtlinie ausgeführtWenn die Anzahl der Kernthreads 5 beträgt, beträgt die Warteschlangenlänge 3 und die maximale Anzahl der Threads beträgt 7: Wenn die Anzahl der Threads weiter zunimmt, erstellen Sie zuerst 5 Kernthreads Wenn die Warteschlange voll ist, werden Threads in die Warteschlange geworfen. Wenn sich 2 Threads in der Warteschlange befinden, ist die maximale Anzahl an Threads erreicht (5+2=7), die Warteschlange ist jedoch noch nicht voll, sodass dies nicht erforderlich ist Sorgen Sie sich um die maximale Anzahl von Threads, bis die Warteschlange voll ist (3 blockierte Threads). Zu diesem Zeitpunkt wird die maximale Anzahl von Threads verglichen (nur wenn die Warteschlange voll ist und die maximale Anzahl von Threads beendet werden kann). + Warteschlange = 5+3=8>7= Die maximale Anzahl an Threads, d. h. die maximale Anzahl an Threads wurde erreicht, dann wird die Ablehnungsrichtlinie ausgeführt Wenn die Warteschlange auf LinkedBlockingQueue eingestellt ist Unbegrenzte Warteschlange, diese Warteschlange ist unendlich und wird niemals die maximale Thread-Bestimmung erreichen. Zählen Sie diesen Schritt
可以使用有界队列,自定义线程创建工厂ThreadFactory和拒绝策略handler来自定义线程池
public class ThreadTest { public static void main(String[] args) throws InterruptedException, IOException { int corePoolSize = 2; int maximumPoolSize = 4; long keepAliveTime = 10; TimeUnit unit = TimeUnit.SECONDS; BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2); ThreadFactory threadFactory = new NameTreadFactory(); RejectedExecutionHandler handler = new MyIgnorePolicy(); ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); executor.prestartAllCoreThreads(); // 预启动所有核心线程 for (int i = 1; i <= 10; i++) { MyTask task = new MyTask(String.valueOf(i)); executor.execute(task); } System.in.read(); //阻塞主线程 } static class NameTreadFactory implements ThreadFactory { private final AtomicInteger mThreadNum = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement()); System.out.println(t.getName() + " has been created"); return t; } } public static class MyIgnorePolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { doLog(r, e); } private void doLog(Runnable r, ThreadPoolExecutor e) { // 可做日志记录等 System.err.println( r.toString() + " rejected"); // System.out.println("completedTaskCount: " + e.getCompletedTaskCount()); } } static class MyTask implements Runnable { private String name; public MyTask(String name) { this.name = name; } @Override public void run() { try { System.out.println(this.toString() + " is running!"); Thread.sleep(3000); //让任务执行慢点 } catch (InterruptedException e) { e.printStackTrace(); } } public String getName() { return name; } @Override public String toString() { return "MyTask [name=" + name + "]"; } } }
运行结果:
其中7-10号线程被拒绝策略拒绝了,1、2号线程执行完后,3、6号线程进入核心线程池执行,此时4、5号线程在任务队列等待执行,3、6线程执行完再通知4、5线程执行
Das obige ist der detaillierte Inhalt vonWelche vier Thread-Pools gibt es in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!