Применение метода спекулятивного выполнения для распараллеливания исходного кода, содержащего обработку исключений - page 8

// Однопоточный код
if (loopThr == null)
// Если никакое исключение не сгенерировано, просто запишем
// последнее значение
someVar = lastWrite;
else {
// иначе ищем последнюю возможную запись в списке записей
int numToFind = iterExcNo - 1;
if (numToFind
>
0) {
for (Object obj : someVarWrites) {
Pair<int, int> pair = (Pair<int, int>)obj;
if (pair.getFirst() == numToFind)
someVar = iterExcNo;
}
}
// генерация сохранeнного исключения
throw loopThr;
}
Если использовать оптимизации, связанные с обработкой циклов,
в частности массив, то результирующий код можно значительно упро-
стить. Оптимизированный код показан в листинге 3.
Листинг 3.
Распараллеленный цикл с обработкой исключения с
дополнительными оптимизациями:
int someVar;
int threadExcNo = nThreads - 1;
final Object syncObj = new Object();
ThrowableloopThr = null;
// volatile здесь не нужен, поскольку каждый поток работает со своим
// элементом массива, а однопоточный код имеет барьер памяти
// после Thread.join() [12]
Integer someVarWrites = new Integer[nThreads];
// Запускаем потоки или применяем задачу для существующего пула
for (int j = 0; j
<
nThreads; j++) {
new Thread(new Runnable() {
public void run() {
try {
// Раздел¨eнный на итерации цикл
for (int i = j*nThreads; i < j*(nThreads + 1) &&
(loopThr != null && threadExcNo
>
j); i++) {
throwingOperation();
int value = someOp();
someVarWrites[i] = new Integer(value);
}
} catch (Throwable thr) {
synchronized (syncObj) {
if (j <= threadExcNo) {
threadExcNo =j;
loopThr = thr;
}
}
78 ISSN 0236-3933. Вестник МГТУ им. Н.Э. Баумана. Сер. “Приборостроение”. 2014. № 6
1,2,3,4,5,6,7 9,10,11,12,13
Powered by FlippingBook