ThreadPoolExecutor - 1

„Обикновените програмисти рано or късно се справят с факта, че имат много малки задачи, които трябва да се изпълняват от време на време.“

„Ако пишете игра, това са действията, които отделните герои извършват.“

„Ако пишете уеб сървър, това са различни команди, идващи от потребителите: качете снимка, преcodeирайте я в желания формат, приложете желания шаблон и т.н.“

"Рано or късно всички големи задачи се разделят на набор от малки, управляеми задачи."

„И така, като се има предвид този контекст, възниква тънък въпрос: How се предполага да ги управлявате? Какво ще стане, ако трябва да изпълните няколкостотин задачи за minutesа? Създаването на нишка за всяка задача няма да има много смисъл. Java машината разпределя доста ресурси за всяка нишка."

„С други думи, създаването и унищожаването на нишка може да отнеме повече време и ресурси, отколкото самата задача.“

„Създателите на Java измислиха елегантно решение на този проблем: ThreadPoolExecutor .

" ThreadPoolExecutor е клас с две неща вътре:"

A)  Опашка със задачи, към която можете да добавяте задачи, когато възникнат в програмата.

B) Пул от нишки, който е група от нишки, които изпълняват тези задачи.

"Нещо повече, нишките не се унищожават, след като задачата приключи. Вместо това те заспиват, за да бъдат готови да започнат нова задача веднага щом се появи."

„Когато създавате ThreadPoolExecutor , можете да зададете максималния брой нишки, които да бъдат създадени, и максималния брой задачи, които могат да бъдат поставени на опашка. С други думи, можете да ограничите броя на нишките до 10, например, и броя на поставени задачи на опашка до 100."

„Ето How работи ThreadPoolExecutor :“

1)  Когато добавите нова задача, тя се поставя в края на опашката.

2)  Ако опашката е пълна, се хвърля изключение.

3)  При завършване на задача всяка нишка взема следващата задача от опашката и започва да я изпълнява.

4) Ако няма задачи в опашката, нишката заспива, докато не бъдат добавени нови задачи.

„Подходът, при който ограничаваме броя на работните нишки, е изгоден с това, че колкото повече нишки имаме, толкова повече те си пречат една на друга. Много по-ефективно е да имате 5-10 работни нишки и дълга опашка от задачи, отколкото да създадете 100 нишки за вълна от задачи, които ще се конкурират помежду си за ресурси: памет, процесорно време, достъп до база данни и т.н."

„Ето пример за ThreadPoolExecutor в действие:“

Пример
ExecutorService service = Executors.newFixedThreadPool(2);

for(int i = 0; i < 10; i++)
{
 service.submit(new Runnable() {
    public void run()
    {
     // Here we download something big from the Internet.
    }
 });
}

— Ъъъ, не го виждам…

„ Обект ThreadPoolExecutor се създава, когато се извика методът newFixedThreadPool.“

Така че е много лесен за използване. Веднага след като добавите задача към нея с метода за изпращане, тя:

A)  Събужда спяща нишка, ако има такава, за да изпълни задачата.

B)  Ако няма чакаща нишка, тогава се създава нова за задачата.

C)  Ако се достигне максималният брой нишки, тогава задачата просто се поставя в края на опашката.

„Нарочно включих „тук изтегляме нещо голямо от интернет“ в примера. Ако имаме 100 задачи „изтеглете нещо голямо от интернет“, тогава няма смисъл да изпълняваме много от тях едновременно – ние ще бъде задържан от ограничението на честотната лента на нашата интернет връзка. В този случай няколко нишки трябва да са достатъчни. Ето Howво виждате в примера по-горе:"

ExecutorService service = Executors.newFixedThreadPool(2);

„Оказва се, че работата с куп задачи не е толкова трудна.

"Да. Дори по-лесно, отколкото може да си представите. Но Ким ще ви разкаже за това."