Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

// concurrency/Pool java

// Использование Semaphore в Pool ограничивает количество // задач, которые могут использовать ресурс import java util concurrent *. import java util *,

public class Pool<T> { private int size,

private List<T> items = new ArrayList<T>; private volatile boolean[] checkedOut, private Semaphore available, public Pool(Class<T> classObject, int size) { this.size = size, checkedOut = new boolean[size], available = new Semaphore(size, true); // Заполнение

пула объектами for(int i =0, i < size, ++i) try {

// Предполагается наличие конструктора по умолчанию items add(classObject newInstanceO). } catch(Exception e) {

throw new RuntimeException(e);

}

}

public T checkout О throws InterruptedException { available acquireO; return getltemO,

}

public void checkIn(T x) { if(releaseltem(x))

available releasee);

}

private synchronized T getltemO {

for(int i =0; i < size, ++i) if(!checkedOut[i]) {

checkedOut[i] = true, return items get(i);

}

return null. // Семафор предотвращает переход в зту точку

}

private synchronized boolean releaseItem(T item) { int index = items indexOf(item). if(index == -1) return false; // Отсутствует в списке if(checkedOut[index]) {

checkedOut[index] = false, return true,

}

return false; // He был освобожден

}

В этой упрощенной форме конструктор использует newlnstance для заполнения пула объектами. Если вам понадобится новый объект, вызовите check-Out; завершив работу с объектом, передайте его checkln.

Логический массив checkedOut отслеживает выданные объекты. Для управления его содержимым используются методы getltem и releaseltem. В свою очередь, эти методы защищены семафором available, поэтому в checkOut семафор available блокирует дальнейшее выполнение при отсутствии семафорных разрешений (то есть при отсутствии объектов в пуле). Метод checkln проверяет действительность возвращаемого объекта, и, если объект действителен, разрешение возвращается семафору.

Для примера мы воспользуемся классом Fat. Создание объектов этого класса является высокозатратной операцией, а на выполнение конструктора уходит много времени:

//: concurrency/Fat java

// Объекты, создание которых занимает много времени

public class Fat {

private volatile double d. // Предотвращает оптимизацию private static int counter = 0. private final int id = counter++. public FatО {

// Затратная, прервываемая операция for(int i = 1: i < 10000; i++) {

d += (Math PI + Math.E) / (double)i.

}

}

public void operationO { System out println(this); } public String toStringO { return "Fat id: " + id; } } ///:-

Мы создадим пул объектов Fat, чтобы свести к минимуму затраты на выполнение конструктора. Для тестирования класса Pool будет создана задача, которая забирает

объекты Fat для использования, удерживает их в течение некоторого времени, а затем возвращает обратно:

// concurrency/SemaphoreDemo java // Тестирование класса Pool import java.util.concurrent.*; import java util *;

import static net.mindview.util.Print.*;

// Задача для получения ресурса из пула: class CheckoutTask<T> implements Runnable { private static int counter = 0; private final int id = counter++; private Pool<T> pool. public CheckoutTask(Pool<T> pool) { this.pool = pool;

}

public void run { try {

T item = pool.checkoutО;

print(this + "checked out " + item); продолжение &

TimeUnit SECONDS sleep(l), pri nt(thi s +"checking in " + item), pool checkln(item). } catch(InterruptedException e) {

// Приемлемый способ завершения

}

}

public String toStringO {

return "CheckoutTask " + id + " ";

public class SemaphoreDemo {

final static int SIZE = 25;

public static void main(String[] args) throws Exception { final Pool<Fat> pool =

new Pool<Fat>(Fat.class. SIZE). ExecutorService exec = Executors newCachedThreadPoolО. for(int i = 0; i < SIZE; i++)

exec.execute(new CheckoutTask<Fat>(pool)). print("All CheckoutTasks created"); List<Fat> list = new ArrayList<Fat>0. for(int i = 0; i < SIZE; i++) { Fat f = pool.checkout О. printnb(i + " mainO thread checked out "). f operationO; list add(f);

}

Future<?> blocked = exec submit(new RunnableO { public void runO { try {

// Семафор предотвращает лишний вызов checkout. // поэтому следующий вызов блокируется: pool checkOutO. } catch(InterruptedException e) {

pri nt("checkout Interrupted");

}

}

}):

TimeUnit.SECONDS sleep(2);

blocked.cancel(true); // Выход из заблокированного вызова print("Checking in objects in " + list); for(Fat f • list)

pool checkln(f); for(Fat f : list)

pool.checkln(f); // Второй вызов checkln игнорируется exec.shutdown О;

}

} ///:-

В коде main создается объект Pool для хранения объектов Fat, после чего группа задач CheckoutTask начинает использовать Pool. Далее поток main начинает выдавать объекты Fat, не возвращая их обратно. После того как все объекты пула будут выданы, семафор запрещает дальнейшие выдачи. Метод run блокируется, и через две секунды вызывается метод cancel. Лишние возвраты Pool игнорирует.

Поделиться:
Популярные книги

70 Рублей

Кожевников Павел
1. 70 Рублей
Фантастика:
фэнтези
боевая фантастика
попаданцы
постапокалипсис
6.00
рейтинг книги
70 Рублей

Переписка 1826-1837

Пушкин Александр Сергеевич
Документальная литература:
публицистика
5.00
рейтинг книги
Переписка 1826-1837

Морской волк. 1-я Трилогия

Савин Владислав
1. Морской волк
Фантастика:
альтернативная история
8.71
рейтинг книги
Морской волк. 1-я Трилогия

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Честное пионерское! Часть 4

Федин Андрей Анатольевич
4. Честное пионерское!
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Честное пионерское! Часть 4

Здравствуйте, я ваша ведьма! Трилогия

Андрианова Татьяна
Здравствуйте, я ваша ведьма!
Фантастика:
юмористическая фантастика
8.78
рейтинг книги
Здравствуйте, я ваша ведьма! Трилогия

Мое ускорение

Иванов Дмитрий
5. Девяностые
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Мое ускорение

Прорвемся, опера! Книга 2

Киров Никита
2. Опер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прорвемся, опера! Книга 2

Невеста напрокат

Завгородняя Анна Александровна
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Невеста напрокат

Если твой босс... монстр!

Райская Ольга
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Если твой босс... монстр!

Приватная жизнь профессора механики

Гулиа Нурбей Владимирович
Проза:
современная проза
5.00
рейтинг книги
Приватная жизнь профессора механики

Попытка возврата. Тетралогия

Конюшевский Владислав Николаевич
Попытка возврата
Фантастика:
альтернативная история
9.26
рейтинг книги
Попытка возврата. Тетралогия

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Аргумент барона Бронина 3

Ковальчук Олег Валентинович
3. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 3