Есть класс MyMath, в котором реализованы математические вычисления в виде static методов. Каждый из static методов получает параметр и при вычислениях пользуется только им или локальными переменными-примитивами метода (т.е. потокобезопасен). Некоторые из методов вычисляются довольно долго (некоторые даже в пределах нескольких секунд).
Предполагается вызов этих методов из множества разных потоков. Эти потоки создаются в
разных местах наподобие:
Runnable myTask = () -> { ... у1=MyMath.calc1(x1); ... уN=MyMath.calcN(xN) ...};
new Thread(myTask).start()
;
Как грамотно с точки зрения производительности и юзабельности кода все это создать (пока статик методы классы + вызов из создаваемых потоков)?
Может единый для всех ThreadPoolExecutor + помещаем в него вычисления оформленные как Callable ?
Может при динамическом создании потока в него засунуть тело функции (тогда будет дублирование, что плохо, но скорость выполнения возрастет) ?
Аналога c-ного inline я так понимаю нет.
Пусть
class MyMAth {
public static double myCalc(double x) {
double res=0;
for(i=0;i< 1000000;i++)
res += страшная матан формула, зависящая от i и от x;
return res;
}
}
Если допустим 50 потоков вызывают MyMath.myCalc(x) то процессор при переключение потоков каждый раз: при прерывании вычисления функции останавливает очередную итерацию цикла + сохраняет состояние переменных, а при ее пробуждении - восстанавливает состояние этого же цикла для других переменных + продолжает вычислять.
Вопрос 2 - При выполнении он дополнительно копирует код static функции (который идентичен) отдельно для каждого процесса (чтобы в дальнейшем кешировать его в блоке кода для каждого ядра) или нет? Или при переключении между потоками просто копирует/восстанавливает состояние регистров и прочих служебных областей, а потом каждый раз копирует снова участок кода static функции?