Try English version of Quizful



Раздаем бесплатные Q! подробности в группе Quizful.Alpha-test
Партнеры
Рекрутерам: Прескрининг кандидатов about
Топ контрибуторов
loading
loading
Знаете ли Вы, что

Вы можете подписаться на RSS ленту новых тестов сервиса Quizful, в том числе и отдельно по каждой категории

Лента обновлений
ссылка 20:57:36
Комментарий от Recrut_rf:
Спасибо, сохранил функцию, может пригодится когда - ни...
ссылка 20:53:59
Добавлен вопрос в тест ASP.NET - Основы
ссылка 08:41:09
Комментарий от Krosster:
Гарний сайт для новачків. Правда деякі питання підступн...
ссылка Apr 22 22:06
Добавлен вопрос в тест SQL - Средний уровень
ссылка Apr 22 10:13
Комментарий от Entrery:
вроде выбрал ООП в сишарпе, а тут вопросы по джаве...
Статистика

Тестов: 153, вопросов: 8596. Пройдено: 402470 / 1961091.

Thread pool pattern

head tail Статья
категория
Java
дата05.02.2013
авторYuriyDunko
голосов6

Очень полезный и сложный паттерн Thread-pool-pattern, зачастую остается без внимания. Я попытаюсь на пальцах и немногословно объяснить зачем он и как его использовать.

Допустим мы модулируем предприятие, у нас имеется: 1 менеджер, N работников (В нашем примере N будет жестко заданно, как зачастую оно бывает), предприятие и источник работы (имеется ввиду поступающие задачи). Таким образом нам надо как можно эффективней использовать наших работников и при появлении новой задачи отдавать ее свободному работнику. Если все работники заняты, то задача ждет свободного работника и как только такой появляется он сразу ею займется.

С чего мы начнем, первое это создадим нашего абстрактного работника основным назначением которого есть делать работу и (надеюсь по понятным причинам) должен быть представлен в виде потока.

publicinterface Worker extends Runnable {

}

Для простоты решения создадим класс генерации задач

public class GenTask {

/** dont need delay when geting task*/

private static final int NO_NEED_TIMEOUT = 0;

/** need short when geting task */

private static final int SMALL_TIMEOUT = 1;

/** need not long when geting task */

private static final int MEDIUM_TIMEOUT = 2;

/** need long when geting task */

private static final int HEIGHT_TIMEOUT = 3;

 

/** time of short delay in milesiconds */

private static final int TIMEOUT_SMALL = 100;

/** time of not long delay in milesiconds */

private static final int TIMEOUT_MEDIUM = 300;

/** time of long delay in milesiconds */

private static final int TIMEOUT_HEIGHT = 1000;

private Random random = new Random();

/**

* generate task

*

* 50% - the dont hapen time delay

* 16% - hapen short time delay

* 16% - hapen not long time delay

* 16% - hapen long time delay

*

* @return new task;

*/

public Task next(){

int needDelay = random.nextInt(2);

if (needDelay > 0) {

needDelay = random.nextInt(3) + 1;

try {

switch (needDelay) {

case SMALL_TIMEOUT:

Thread.sleep(TIMEOUT_SMALL);

break;

case MEDIUM_TIMEOUT:

Thread.sleep(TIMEOUT_MEDIUM);

break;

case HEIGHT_TIMEOUT:

Thread.sleep(TIMEOUT_HEIGHT);

break;

default:

System.err.println(getClass().getCanonicalName());

System.err.println(needDelay);

System.exit(1);

}

catch (InterruptedException ex) {

}

}

return new Product();

}

}

Допустим у нас есть некий потребитель (Consumer). Опишу работу менеджера (реализация простая и является примером использования паттерна, поэтому потребитель будет создан менеджером, как вы понимаете на самом деле все будет сложнее).

public class Producer implements Worker{

public static int DEFAULT_LOOPS = 100;

private int loops;

private Consumer consumer;

public Producer(int loops) {

this.loops = loops;

consumer = new Consumer();

}

public Producer() {

this(DEFAULT_LOOPS);

}

public void run() {

GenTask gt = new GenTask();

for (int i = 0; i < loops; i++) {

Task t = gt.next();

System.out.println("PUT " + i);

consumer.put(t);

}

}

}

Для связи простых рабочих (которые делают конкретную работу) и потребителя у нас будет Bridge (Thread Pool) это сложный паттерн и зачастую части его реализации это Медиатор или прокси, или еще что-то, но у нас все по простому. Работник будет выполнять простую работу.

public class SimpleWorker implements Worker {

    private Bridge queue;

    static boolean shout;

 

    public SimpleWorker(Bridge queue) {

        this.queue = queue;

        //this.shout = false;

    }

 

    public void run() {

        while (! shout){

            Task task = queue.take();

            task.execute();

        }

    }

}

Наш мост будет выглядеть следующим образом:

public class Bridge {

    private static final int WORKER_COUNT = 5;

    private List workers = new ArrayList(WORKER_COUNT);

    private Consumer consumer;

 

    public Bridge(Consumer consumer) {

        this.consumer = consumer;

        for (int i = 0; i < WORKER_COUNT; i++) {

            SimpleWorker w = new SimpleWorker(this);

            Thread t = new Thread(w);

            workers.add(t);

            //w.run();

            t.start();

        }

    }

 

    public synchronized Task take() {

        Task t = consumer.take();

        return t;

    }

 

    @Override

    protected void finalize() throws Throwable {

        super.finalize();

        SimpleWorker.shout = true;

    }

 

}

Подробную информацию про Thread pool pattern и его использование можно почитать здесь http://en.wikipedia.org/wiki/Thread_pool_pattern

Если Вам понравилась статья, проголосуйте за нее

Голосов: 6  loading...
Soffi   chebevara   ELetenkov   DarkTror   SamTan   Astel_denkayo