Проблема в том, что вы вызываете
threadCount = omp_get_num_threads();
вне параллельного блока, так что это 1, и ваш цикл внутри
mulMatrAndVecMP(vec1, A, z, (threadNum * N) / threadCount, N / threadCount, N);
выходит за пределы.
Установка
threadCount = 4
вместо этого должна решить вашу проблему.
Как вы можете прочитать здесь , вызов возвращает количество потоков в текущей команде, а текущей команды нет.
Редактировать: будьте осторожны, если N не делится на количество потоков: ваш код пропускает некоторые строки умножения.
Довольно простая опция состоит в том, чтобы обернуть Ваш BlockingQueue
с реализацией, которая звонит put(..)
, когда offer(..)
вызывается:
public class BlockOnOfferAdapter<T> implements BlockingQueue<T> {
(..)
public boolean offer(E o) {
try {
delegate.put(o);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
return true;
}
(.. implement all other methods simply by delegating ..)
}
Это работает, потому что значением по умолчанию put(..)
ожидает, пока нет способность в очереди, когда это полно, см. :
/**
* Inserts the specified element into this queue, waiting if necessary
* for space to become available.
*
* @param e the element to add
* @throws InterruptedException if interrupted while waiting
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this queue
*/
void put(E e) throws InterruptedException;
Никакая ловля RejectedExecutionException
или сложная необходимая блокировка.
В некоторых очень узких обстоятельствах вы можете реализовать java.util.concurrent.RejectedExecutionHandler, который сделает то, что вам нужно.
RejectedExecutionHandler block = new RejectedExecutionHandler() {
rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
executor.getQueue().put( r );
}
};
ThreadPoolExecutor pool = new ...
pool.setRejectedExecutionHandler(block);
Сейчас. Это очень плохая идея по следующим причинам
Почти всегда лучшая стратегия - установить ThreadPoolExecutor.CallerRunsPolicy, который будет ограничивать ваше приложение, выполняя задачу в потоке, вызывающем execute ().
Однако иногда стратегия блокировки со всеми присущими ей рисками - это действительно то, что вам нужно. Я бы сказал, что в этих условиях
Итак, как я сказал. Это редко нужно и может быть опасно, но вот и все.
Удачи.