Middle+
Fork/Join çərçivəsi nədir və Java-da necə istifadə olunur?
sobes.tech Süni İntellekt
AI-dan cavab
Fork/Join çərçivəsi — bu, Executor çərçivəsinin ixtisaslaşdırılmış bir tətbiqidir və təkrarlana bilən və daha kiçik alt tapşırıqlara bölünə bilən və sonra nəticələri birləşdirilə bilən tapşırıqları səmərəli şəkildə paralelləşdirmək üçün nəzərdə tutulmuşdur. Bu, "böl və fəth et" prinsipinə əsaslanır.
Əsas komponentlər:
ForkJoinPool: Tapşırıqları icra edən işçi hovuzu. Bu, "work-stealing" mexanizmini istifadə edir, burada hovuzdakı boş işləyən işçilər digər məşğul olan işçilərdən tapşırıqları oğurlaya bilərlər.ForkJoinTask: Bu çərçivədə icra oluna bilən tapşırığı təmsil edən abstrakt sinif. İki növü var:RecursiveAction: Nəticə qaytarmayan tapşırıq.RecursiveTask<V>:Vtipində nəticə qaytaran tapşırıq.
İstifadə:
RecursiveActionvə yaRecursiveTask-ı miras alan sinif yaradılır.compute()metodu yenidən yazılır. Bu metodda lojiq qeyd olunur:- Əgər tapşırıq kifayət qədər kiçikdirsə (müəyyən bir sərhəddən azdırsa), birbaşa icra olunur.
- Əks halda, tapşırıq alt tapşırıqlara bölünür və
fork()metodu ilə asinxron şəkildə icra olunur. - Alt tapşırıqların
join()metodu ilə tamamlanması gözlənir və nəticələri birləşdirilir.
ForkJoinPoolnümunəsi yaradılır.- Tapşırıq
invoke()və yasubmit()metodları ilə hovuzda təqdim olunur.
Misal:
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SumArrayTask extends RecursiveTask<Long> {
private final long[] array;
private final int start;
private final int end;
private static final int THRESHOLD = 1000; // Sərhəd dəyəri
public SumArrayTask(long[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if (end - start <= THRESHOLD) {
// Kiçik diapazonlar üçün birbaşa hesablamalar
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
// Tapşırığın bölünməsi
int mid = start + (end - start) / 2;
SumArrayTask leftTask = new SumArrayTask(array, start, mid);
SumArrayTask rightTask = new SumArrayTask(array, mid, end);
// Alt tapşırıqların asinxron icrası
leftTask.fork();
Long rightResult = rightTask.compute();
Long leftResult = leftTask.join();
// Nəticələrin birləşdirilməsi
return leftResult + rightResult;
}
}
}
// Əsas kodda istifadə
// long[] data = new long[10000]; // Başlanğıc məlumatlar
// // data doldurulur
// ForkJoinPool pool = new ForkJoinPool();
// long sum = pool.invoke(new SumArrayTask(data, 0, data.length));
// pool.shutdown(); // İstifadədən sonra hovuzu bağla
Üstünlüklər:
- İşçi hovuzunun avtomatik idarə olunması.
- Work-stealing sayəsində yükün səmərəli bölünməsi.
- "Böl və fəth et" tipli tapşırıqlar üçün yaxşı performans.
Çatışmazlıqlar:
- Bütün paralel tapşırıqlar üçün uyğun deyil.
- Sadə tapşırıqlar üçün digər yanaşmalara nisbətən daha çətin ola bilər.