АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

WAITING

Читайте также:
  1. IAMWAITING

Потоки в J2SE 5

Java всегда предлагала широкие возможности для мультипрограммирования: потоки – это основа языка. Однако очень часто использование таких возможностей становилось ловушкой: правильно написать и отладить многопоточную программу достаточно сложно.

В версии 1.5 языка добавлены пакеты классов java.util.concurrent.locks, java.util.concurrent.atomic, java.util.concurrent, возможности которых обеспечивают более высокую производительность, масштабируемость, построение потокобезопасных блоков параллельных (concurrent) классов, вызов утилит синхронизации, использование семафоров, ключей и atomic-переменных.

Возможности синхронизации существовали и ранее. Практически это означало, что синхронизированные объекты блокировались, хотя необходимо это было далеко не всегда. Например, поток, изменяющий одну часть объекта Hashtable, блокировал работу других потоков, которые хотели прочесть (даже не изменить) совсем другую часть этого объекта. Поэтому введение дополнительных возможностей, связанных с синхронизаций потоков и блокировкой ресурсов довольно логично.

Ограниченно потокобезопасные (thread safe) коллекции и вспомогательные классы управления потоками сосредоточены в пакете java.util.concurrent. Среди них можно отметить:

· параллельные классы очередей ArrayBlockingQueue (FIFO очередь с фиксированой длиной), PriorityBlockingQueue (очередь с приоритетом) и ConcurrentLinkedQueue (FIFO очередь с нефиксированой длиной);

· параллельные аналоги существующих синхронизированых классов-коллекций ConcurrentHashMap (аналог Hashtable) и
CopyOnWriteArrayList (реализация List, оптимизированная для случая, когда количество итераций во много раз превосходит количество вставок и удалений);

· механизм управления заданиями, основанный на возможностях класса Executor, включающий пул потоков и службу их планирования;

· высокопроизводительный класс Lock, поддерживающий ограниченные ожидания снятия блокировки, прерываемые попытки блокировки, очереди блокировки и установку ожидания снятия нескольких блокиро­вок посредством класса Condition;

· классы атомарных переменных (AtomicInteger, AtomicLong,
AtomicReference), а также их высокопроизводительные аналоги SyncronizedInt и др.;

· классы синхронизации общего назначения, такие как Semaphore, CountDownLatch (позволяет потоку ожидать завершения нескольких операций в других потоках), CyclicBarrier (позволяет нескольким потокам ожидать момента, когда они все достигнут какой-либо точки) и Exchanger (позволяет потокам синхронизироваться и обмениваться информацией);

· обработка неотловленных прерываний: класс Thread теперь поддерживает установку обработчика на неотловленные прерывания (подобное ранее было доступно только в ThreadGroup).

Хорошим примером новых возможностей является синхронизация коллекции типа Hashtable. Объект Hashtable синхронизируется целиком, и если один поток занял кэш остальные потоки вынуждены ожидать освобождения объекта. В случае же использования нового класса ConcurrentHashMap практически все операции чтения могут проходить одновременно, операции чтения и записи практически не задерживают друг друга, и только одновременные попытки записи могут блокироваться. В случае же использования данного класса как кэша (спецификой которого является большое количество операций чтения и малое – записи), блокироваться многопоточный код практически не будет.

В таблице приведено время выполнения (в миллисекундах) программы, использовавшей в качестве кэша ConcurrentHashMap и Hashtable. Тесты проводились на двухпроцессорном сервере под управлением Linux. Количество данных для большего количества потоков увеличивалось.

Количество потоков ConcurrentHashMap Hashtable
  1.00 1.03
  2.59 32.40
  5.58 78.23
  13.21 163.48
  27.58 341.21
  57.27 778.41

// пример # 13: применение семафора: Sort.java: ArraySort.java

package chapt14;

import java.util.concurrent.*;

 

public class Sort {

public static final int ITEMS_COUNT = 15;

public static double items [];

// семафор, контролирующий разрешение на доступ к элементам массива

public static Semaphore sortSemaphore =

new Semaphore(0, true);

 

public static void main(String[] args) {

items = new double [ ITEMS_COUNT ];

for (int i = 0; i < items.length; ++i)

items [i] = Math. random ();

new Thread(new ArraySort(items)).start();

for (int i = 0; i < items. length; ++i) {

/*

* при проверке доступности элемента сортируемого

* массива происходит блокировка главного потока

* до освобождения семафора

*/

sortSemaphore. acquireUninterruptibly();

System. out. println(items [i]);

}

}

}

class ArraySort implements Runnable {

private double items[];

 

public ArraySort(double items[]) {

this. items = items;

}

public void run(){

for (int i = 0; i < items.length - 1; ++i) {

for (int j = i + 1; j < items.length; ++j) {

if (items[i] < items[j]) {

double tmp = items[i];

items[i] = items[j];

items[j] = tmp;

}

}

// освобождение семафора

Sort. sortSemaphore. release();

try {

Thread. sleep (71);

} catch (InterruptedException e) {

System. err. print(e);

}

}

Sort. sortSemaphore. release();

}

}

Задания к главе 14

Вариант А

1. Cоздать апплет с использованием потоков: строка движется горизонтально, отражаясь от границ апплета и меняя при этом случайным образом свой цвет.

2. Cоздать апплет с использованием потоков: строка движется по диагонали. При достижении границ апплета все символы строки случайным образом меняют регистр.

3. Организовать сортировку массива методами Шелла, Хоара, пузырька, на основе бинарного дерева в разных потоках.

4. Реализовать сортировку графических объектов, используя алгоритмы из задания 3.

5. Создать апплет с точкой, движущейся по окружности с постоянной угловой скоростью. Сворачивание браузера должно приводить к изменению угловой скорости движения точки для следующего запуска потока.

6. Изобразить точку, пересекающую с постоянной скоростью окно слева направо (справа налево) параллельно горизонтальной оси. Как только точка доходит до границы окна, в этот момент от левого (правого) края с вертикальной координатной y, выбранной с помощью датчика случайных чисел, начинает свое движение другая точка и т.д. Цвет точки также можно выбирать с помощью датчика случайных чисел. Для каждой точки создается собственный поток.

7. Изобразить в приложении правильные треугольники, вращающиеся
в плоскости экрана вокруг своего центра. Каждому объекту соответствует поток с заданным приоритетом.

8. Условие предыдущей задачи изменяется таким образом, что центр вращения перемещается от одного края окна до другого с постоянной скоростью параллельно горизонтальной оси.

9. Cоздать фрейм с тремя шариками, одновременно летающими в окне.
С каждым шариком связан свой поток со своим приоритетом.

10. Два изображения выводятся в окно. Затем они постепенно исчезают
с различной скоростью в различных потоках (случайным образом выбираются точки изображения, и их цвет устанавливается в цвет фона).

11. Условие предыдущей задачи изменить на применение эффекта постепенного “проявления” двух изображений.

Вариант B

Для заданий варианта В главы 4 организовать синхронизированный доступ к ресурсам (файлам). Для каждого процесса создать отдельный поток выполнения.

Тестовые задания к главе 14

Вопрос 14.1.

Дан код:

class Q implements Runnable{

int i = 0;

public int run(){

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

return i;

}}

public class Quest1 {

public static void main(String[] args) {

Q ob = new Q();

ob.run();

}}

При попытке компиляции и запуска будет выведено:

1) i = 0;

2) i = 1;

3) ошибка компиляции: создать объект потока можно только с помощью инициализации объекта класса Thread или его наследников;

4) ошибка компиляции: неправильно реализован метод run();

5) ошибка времени выполнения: поток должен запускаться методом start().

Вопрос 14.2.

Дан код:

Thread t1= new Thread();

t1.setPriority(7);

ThreadGroup tg= new ThreadGroup("TG");

tg.setMaxPriority(8);

Thread t2= new Thread(tg,"t2");

System.out.print("приоритет t1="

+ t1.getPriority());

System.out.print(", приоритет t2="

+ t2.getPriority());

В результате компиляции и выполнения будет выведено:

1) приоритет t1 = 7, приоритет t2 = 5;

2) приоритет t1 = 7, приоритет t2 = 8;

3) приоритет t1 = 10, приоритет t2 = 8;

4) нет правильного.


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.)