Form/Join Framework - это реализация интерфейса expersorservice, с помощью которого мы можем реализовать несколько процессов. Вилка/соединение может использоваться для рекурсивного разделения большой задачи на несколько небольших задач, с целью полного использования всех ресурсов для максимально возможного повышения производительности приложения.
Как и любая реализация интерфейса experserservice, Fork/Join также использует пулы потоков для распределения потоков работников. Что уникально в структуре вилки/соединения, так это то, что он использует алгоритм очистки работы. Благодаря этому алгоритму, рабочие потоки могут красть другие задачи занятых потоков для выполнения, когда ничего нельзя сделать.
Ядром структуры вилки/соединения является класс Forkjoinpool, подкласс класса AbstractExeCutorService. Forkjoinpool реализует основной алгоритм очистки работы и может выполнять обработку forkjointask.
Основное использование
Первым шагом в использовании Framework вилки/соединения является написание кода, который выполняет фрагментированные задачи. Записанный код аналогичен следующему псевдокоду:
Если задача достаточно мала: выполните задачу непосредственно еще: Нарежьте задачу на две небольшие задачи, чтобы выполнить две небольшие задачи и дождитесь результата
Используйте подкласс Forkjointask, чтобы инкапсулировать код, как указано выше. Обычно используются некоторые классы, предоставленные JDK, в том числе Recursivetask (этот класс вернет результат) и рецирурсивиакция.
После подготовки подкласса Forkjointask создайте объект, представляющий все задачи, и передайте его методу invoke () экземпляра Forkjoinpool.
От размытия до чистого
Чтобы помочь понять, как работает структура вилки/соединения, мы используем корпус для иллюстрации: например, размывая изображение. Мы представляем изображение с использованием целочисленного массива, где каждое числовое значение представляет цвет пикселя. Размытое изображение также представлено массивом той же длины.
Выполнение размытия достигается путем обработки каждого пикселя, представляющего изображение. Рассчитайте среднее значение каждого пикселя и окружающих его пикселей (среднее из трех основных цветов красного, желтого и синего), и результирующее множество результатов - размытая картина. Поскольку представление изображений обычно является большим массивом, весь процесс обычно занимает много времени. Структура вилки/соединения может использоваться для использования преимуществ одновременной обработки в многопроцессорных системах для ускорения. Вот возможная реализация:
пакет com.zhyea.robin; Импорт java.util.concurrent.recursivaction; Общедоступный класс Forkblur расширяет рецирсивизацию {private int [] msource; частный int mStart; частный int mlength; Частный int [] mdestination; // обрабатывать размер окна; Это должно быть нечетное число. Частный int mblurwidth = 15; public bokblur (int [] src, int start, int length, int [] dst) {msource = src; mStart = start; mlength = длина; mdestination = dst; } Protected void ComputErectly () {int sidepixels = (mblurwidth - 1) / 2; for (int index = mStart; index <mStart+mlength; index ++) {// Вычислять среднее значение. float rt = 0, gt = 0, bt = 0; for (int mi = -sidepixels; mi <= sidepixels; mi ++) {int mindex = math.min (math.max (mi+index, 0), msource.length - 1); int pixel = msource [mindex]; rt += (float) ((Pixel & 0x00ff0000) >> 16) / mblurwidth; gt += (float) ((pixel & 0x00000ff00) >> 8) / mblurwidth; bt += (float) ((pixel & 0x000000fff) >> 0) / mblurwidth; } // реорганизовать целевой пиксель. int dpixel = (0xff0000000) | (((int) rt) << 16) | (((int) gt) << 8) | (((int) bt) << 0); mdestination [index] = dpixel; }} ....}Теперь реализуйте Abstract Method Compute (), в котором реализованы обе нечеткие операции, а также разделение задачи на две небольшие задачи. Здесь мы просто решаем, выполнить ли задачу напрямую или разделить ее на две небольшие задачи на основе длины массива:
защищенный статический int sthreshold = 100000; Protected void compute () {if (mlength <sthreshold) {computEredirectly (); возвращаться; } int split = mlength / 2; Invokeall (новый Forkblur (Msource, MSTART, Split, Mdestination), New Forkblur (MSOURCE, MSTART + SPLIT, MLENGE - SPLIT, MDESTINANIAN)); }Поскольку реализация вышеупомянутых методов определяется в подклассе рецирсивиакции, задачи могут быть созданы и запускаться непосредственно в форкжунпуле. Конкретные шаги следующие:
1. Создайте объект, представляющий задачу, которая будет выполнена:
// SRC представляет собой массив пикселей исходного изображения // DST представляет пиксели сгенерированного изображения forkblur fb = new forkblur (src, 0, src.length, dst);
2. Создайте экземпляр Forkjoinpool, который выполняет задачу:
ForkJoinPool pool = new ForkJoinPool();
3. Запустите задачу:
pool.invoke(fb);
Исходный код также содержит некоторый код для создания целевого изображения. Для получения подробной информации обратитесь к примеру Vokblur.
Стандартная реализация
Чтобы использовать Formwork Form/Join для выполнения параллельных задач на многоядерных системах в соответствии с пользовательскими алгоритмами, конечно, вам необходимо реализовать пользовательские классы (например, класс Forkblur, который мы реализовали ранее). Кроме того, некоторые особенности структуры вилки/соединения широко использовались в Javase. Например, метод Parallelsort () класса java.util.arrays в Java8 использует структуру вилки/соединения. Для получения подробной информации, пожалуйста, обратитесь к документации Java API.
Другая реализация структуры вилки/соединения находится в пакете java.util.streams, который также является частью функции Lambda Java8.