Middle+
Fork/Join çərçivəsi nədir və Java-da necə istifadə edilir?
sobes.tech AI
AIден жооп
Fork/Join чөйрөсү — бул Executor чөйрөсүнүн атайын ишке ашыруу, ал эффективдүү түрдө параллелдүү ишти бөлүп, кайра бириктирүүгө мүмкүндүк берет, ал рекурсивдүү түрдө кичирейтилген жана андан кийин (join) алардын натыйжалары бириктирилет. Ал "бөлүү жана бийлик кыл" принцибин негиз кылат.
Негизги компоненттер:
ForkJoinPool: Түзмөктөрдүн пулу, ал ишти аткарууну башкарат. Ал "work-stealing" механизмин колдонуп, анда иштебеген түзмөктөр башка иштеп жаткан түзмөктөрдөн тапшырмаларды уурдап алса болот.ForkJoinTask: Бул абстракттуу класс, ал ушул чөйрөдө аткарылуучу тапшырманы көрсөтөт. Анын эки түрү бар:RecursiveAction: Натыйжасы жок тапшырма.RecursiveTask<V>:Vтүрүндөгү натыйжаны кайтарган тапшырма.
Колдонуу:
RecursiveActionжеRecursiveTaskнегизинде класс түзүлөт.compute()методу кайра жазылат. Бул методдо логика сүрөттөлөт:- Эгер тапшырма жетиштүү кичинекей болсо (белгилүү бир чекиттен аз), ал түздөн-түз аткарылат.
- Башкача болсо, тапшырма бөлүнөт жана
fork()методу менен асинхрондуу түрдө ишке киргизилет. - Подтапшырмаларды
join()методу менен күтүп, алардын натыйжалары бириктирилет.
ForkJoinPoolобъектиси түзүлөт.- Тапшырма пулга
invoke()жеsubmit()аркылуу берилет.
Мисал:
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; // Чекит
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) {
// Кичинекей диапазондор үчүн түздөн-түз эсептөө
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
// Тапшырманы бөлүү
int mid = start + (end - start) / 2;
SumArrayTask leftTask = new SumArrayTask(array, start, mid);
SumArrayTask rightTask = new SumArrayTask(array, mid, end);
// Асинхрон ишке киргизүү
leftTask.fork();
Long rightResult = rightTask.compute();
Long leftResult = leftTask.join();
// Натыйжаларды бириктирүү
return leftResult + rightResult;
}
}
}
// Негизги коддо колдонуу
// long[] data = new long[10000]; // Баштапкы маалыматтар
// // data толтурулат
// ForkJoinPool pool = new ForkJoinPool();
// long sum = pool.invoke(new SumArrayTask(data, 0, data.length));
// pool.shutdown(); // Пулду жабуу колдонгондон кийин
Артыкчылыктары:
- Автоматтык түрдө түзмөктөрдүн пулун башкаруу.
- work-stealing аркылуу жүктү эффективдүү бөлүштүрүү.
- "бөлүү жана бийлик кыл" түрүндөгү тапшырмалар үчүн жогорку натыйжалуулук.
Кемчиликтери:
- Бардык параллелдүү тапшырмаларга ылайыктуу эмес.
- Ишке ашыруусу башкача жолдорго салыштырмалуу кыйын болушу мүмкүн, жөнөкөй тапшырмалар үчүн.