Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторные работы по ТРС.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
201.18 Кб
Скачать
  1. Опанувати методику створення розподiлених програм з використанням портфеля задач.

 

Теоретичнi вiдомостi.

Портфель задач - неупорядковане сховище задач, що чекають на виконання. Задачi кладуться у портфель, що розподiлений мiж декiлькома робочими процесами.

Кожен робочий процес виконує такий основний код:

while (true) {   отримати задачу з портфеля;   if (задач бiльш нема)     break; #вихiд з циклу while   виконати задачу, можливо, породжуючи новi задачи;   }

Цей пiдхiд можна використовувати для:

  • реалiзацiї рекурсивного паралелизму;

  • вирiшення iтеративних проблем з фiксованою кiлькiстью незалежних задач.

Парадигма портфелю має такi кориснi властивостi:

  • Вона дуже проста у використаннi. Достатньо визначити представлення задачi, реалiзувати портфель, запрограмувати виконання задачи i визначити умови завершення роботи алгоритму.

  • Програми, що використовують портфель задач є масштабуємими у тому сенсi, що їх можна використовувати з будь-яким числом процесорiв. Для цього достатньо просто змiнити число робочих процесiв.

  • Спрощується реалiзацiя балансування навантаження. Якщо час виконання рiзних задач рiзний, то деякi з задач будуть виконуватися довше iнших. Але поки задач бiльше нiж робочих процесiв (у 2 - 3 рази), загальнi об'єми обчислень, що виконуються робочими процесорами, будуть приблизно однаковими.

 

Приклад використання портфеля задач за допомогою ExecutorService.

За допомогою виклику Executors.newFixedThreadPool було створено пул на 5 потокiв.

Тепер, у разi появи великої кiлькостi задач, вони будуть виконуватися вже iснуючими потоками.

Тим самим, буде економитись час на створення нових потокiв за рахунок бiльш ефективного використання вже iснуючих потоков з цього пулу.

Виклик методу get у об'екта типу Future змушує текучий потiк очикувати результат виконання вiдповiдним потоком призначеної йому задачi.

import java.util.concurrent.*; import java.util.Random; class CallableImpl implements Callable <Integer> {   private static final Random rand = new Random();   int threadNumber = 0;   public void setThreadNumber( int num) {     threadNumber = num;     }   public Integer call() {     System.out.println( "Callable task(" + threadNumber +       ") begin");     busy();     System.out.println( "Callable task(" + threadNumber +       ") end");     return new Integer( threadNumber);     }   private void busy() {     try {       Thread.sleep( rand.nextInt( 500));       }     catch (InterruptedException e) {}     }   } public class ExecutorServiceDemo {   public static void main( String args[]) {     CallableImpl callable[] = new CallableImpl[10];     Future future[] = new Future[10];     ExecutorService executor =         Executors.newFixedThreadPool( 5);     for (int i = 0; i < 10; ++i) {       callable[i] = new CallableImpl();       callable[i].setThreadNumber( i + 1);       future[i] = executor.submit( callable[i]);       }     for (int i = 0; i < 10; ++i) {       try {         System.out.println( "Future value: " +           future[i].get());         }       catch (Exception e) {         e.printStackTrace();         }       }     executor.shutdown();     }   }