Муқаддима
Мо аллакай дида будем, ки чӣ гуна риштаҳо дар
қисми аввал сохта мешаванд . Боз ба хотир меорем.
Ришта
Thread
чизест, ки дар он кор мекунад
run
, аз ин рӯ биёед
компилятори онлайни java tutorialspoint-ро истифода барем ва рамзи зеринро иҷро кунем:
public class HelloWorld {
public static void main(String []args){
Runnable task = () -> {
System.out.println("Hello World");
};
new Thread(task).start();
}
}
Оё ин ягона вариант барои иҷро кардани супориш дар ришта аст?
java.util.concurrent.Callable
Маълум мешавад, ки
java.lang.Runnable бародар дорад ва номаш
java.util.concurrent.Callable буда , дар Java 1.5 таваллуд шудааст. Фарқиятҳо чист? Агар мо ба JavaDoc-и ин интерфейс бодиққат нигоҳ кунем, мебинем, ки бар хилофи
Runnable
интерфейси нав усулеро эълон мекунад
call
, ки натиҷа медиҳад. Инчунин, ба таври нобаёнӣ он истисноро мепартояд. Яъне, он моро аз зарурати навиштани
try-catch
блокҳо барои истисноҳои тафтишшуда наҷот медиҳад. Аллакай бад нест, дуруст? Ҳоло мо
Runnable
ба ҷои вазифаи нав дорем:
Callable task = () -> {
return "Hello, World!";
};
Аммо бо он чӣ бояд кард? Чаро ба мо ҳатто ба вазифае лозим аст, ки дар ришта иҷро карда мешавад, ки натиҷа медиҳад? Аён аст, ки дар оянда мо интизор мешавем, ки натиҷаи амалҳоеро, ки дар оянда иҷро мешаванд, ба даст орем. Оянда бо забони англисӣ - Оянда. Ва интерфейс бо ҳамон ном вуҷуд дорад:
java.util.concurrent.Future
java.util.concurrent.Future
Интерфейси
java.util.concurrent.Future API-ро барои кор бо вазифаҳое тавсиф мекунад, ки натиҷаҳои онҳоро мо дар оянда ба даст орем: усулҳои ба даст овардани натиҷаҳо, усулҳои санҷиши ҳолат. Мо
Future
ба татбиқи он манфиатдорем
java.util.concurrent.FutureTask . Ин аст
Task
он чизе ки дар он иҷро мешавад
Future
. Чизи ҷолиб дар бораи ин татбиқи он аст, ки он амалӣ мекунад ва
Runnable
. Шумо метавонед ин як навъ адаптери модели кӯҳнаи кор бо супоришҳо дар риштаҳо ва модели навро баррасӣ кунед (ба маънои нав, ки он дар java 1.5 пайдо шудааст). Инак як мисол:
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class HelloWorld {
public static void main(String []args) throws Exception {
Callable task = () -> {
return "Hello, World!";
};
FutureTask<String> future = new FutureTask<>(task);
new Thread(future).start();
System.out.println(future.get());
}
}
Тавре ки аз мисол дида мешавад, бо истифода аз усул мо
get
натиҷаи масъаларо ба даст меорем
task
.
(!) Муҳим, ки дар айни замон бо истифода аз усул натиҷа ба даст меояд,
get
иҷро синхронӣ мешавад. Ба фикри шумо кадом механизм дар ин ҷо истифода мешавад? Дуруст аст, блоки синхронизатсия вуҷуд надорад - бинобар ин мо
ИНТИЗОРИ-ро дар JVisualVM на ҳамчун
monitor
ё
wait
, балки ҳамчун ҳамон як мебинем
park
(зеро механизм истифода мешавад
LockSupport
).
Интерфейсҳои функсионалӣ
Минбаъд мо дар бораи синфҳо аз Java 1.8 сӯҳбат хоҳем кард, аз ин рӯ муқаддима кардани мухтасар муфид хоҳад буд. Биёед рамзи зеринро бубинем:
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "String";
}
};
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
Function<String, Integer> converter = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s);
}
};
Рамзи нолозим зиёд аст, ҳамин тавр не? Ҳар як синфҳои эълоншуда як вазифаи ягонаро иҷро мекунанд, аммо барои тавсифи он мо як қатор codeҳои ёрирасони нолозимро истифода мебарем. Ва таҳиягарони Java низ чунин фикр мекарданд. Аз ин рӯ, онҳо маҷмӯи "интерфейсҳои функсионалӣ" (
@FunctionalInterface
) -ро ҷорӣ карданд ва қарор доданд, ки ҳоло худи Java ҳама чизро барои мо "андеша" мекунад, ба истиснои интерфейсҳои муҳим:
Supplier<String> supplier = () -> "String";
Consumer<String> consumer = s -> System.out.println(s);
Function<String, Integer> converter = s -> Integer.valueOf(s);
Supplier
- провайдер. Он параметр надорад, аммо чизеро бармегардонад, яъне онро таъмин мекунад.
Consumer
- истеъмолкунанда. Он чизеро ҳамчун вуруд (параметр s) мегирад ва бо он коре мекунад, яъне чизеро истеъмол мекунад. Функсияи дигар вуҷуд дорад. Он чизеро ҳамчун вуруд (параметр
s
) мегирад, коре мекунад ва чизеро бармегардонад. Тавре ки мебинем, генерикҳо фаъолона истифода мешаванд. Агар шумо боварӣ надошта бошед, шумо метавонед онҳоро ба ёд оред ва "
Назарияи генерикҳо дар Java ё чӣ гуна гузоштани қавсҳоро дар амал " хонед.
Completable Future
Бо гузашти вақт, Java 1.8 синфи наверо бо номи
CompletableFuture
. Он интерфейсро амалӣ мекунад
Future
, яъне маънои мо
task
дар оянда иҷро хоҳад шуд ва мо метавонем иҷро кунем
get
ва натиҷа ба даст орем. Аммо ӯ баъзеро низ амалӣ мекунад
CompletionStage
. Аз тарчума максади он аллакай маълум аст: ин як мархилаи муайяни як навъ хисоб мебошад. Муқаддимаи мухтасари мавзӯъро дар шарҳи "
Муқаддима ба CompletionStage ва CompletableFuture " пайдо кардан мумкин аст. Биёед рост ба матлаб гузарем. Биёед рӯйхати усулҳои мавҷудаи статикиро дида бароем, то ба мо дар оғоз ёрӣ расонанд:
Дар ин ҷо имконоти истифодаи онҳо инҳоянд:
import java.util.concurrent.CompletableFuture;
public class App {
public static void main(String []args) throws Exception {
CompletableFuture<String> completed;
completed = CompletableFuture.completedFuture("Просто meaning");
CompletableFuture<Void> voidCompletableFuture;
voidCompletableFuture = CompletableFuture.runAsync(() -> {
System.out.println("run " + Thread.currentThread().getName());
});
CompletableFuture<String> supplier;
supplier = CompletableFuture.supplyAsync(() -> {
System.out.println("supply " + Thread.currentThread().getName());
return "Значение";
});
}
}
Агар мо ин codeро иҷро кунем, мо мебинем, ки офариниш
CompletableFuture
оғоз кардани тамоми занҷирро дар бар мегирад. Аз ин рӯ, гарчанде ки бо SteamAPI аз Java8 каме шабоҳат вуҷуд дорад, ин фарқият байни ин равишҳост. Барои намуна:
List<String> array = Arrays.asList("one", "two");
Stream<String> stringStream = array.stream().map(value -> {
System.out.println("Executed");
return value.toUpperCase();
});
Ин як намунаи Java 8 Stream Api аст (шумо метавонед дар ин ҷо бештар дар бораи он хонед "
Дастури Java 8 Stream API дар расмҳо ва мисолҳо "). Агар шумо ин codeро иҷро кунед, он
Executed
намоиш дода намешавад. Яъне ҳангоми сохтани ҷараён дар Java ҷараён фавран оғоз намешавад, балки интизор мешавад, ки аз он арзиш лозим шавад. Аммо
CompletableFuture
он фавран занҷирро барои иҷро оғоз мекунад, бидуни интизори он ки арзиши ҳисобшуда аз он талаб карда шавад. Ман фикр мекунам, ки инро фаҳмидан муҳим аст. Ҳамин тавр, мо CompletableFuture дорем. Чӣ тавр мо метавонем занҷир эҷод кунем ва мо чӣ гуна воситаҳо дорем? Биёед дар бораи интерфейсҳои функсионалӣ, ки мо қаблан навишта будем, ба ёд орем.
- Мо функсияе дорем (
Function
), ки A-ро мегирад ва B-ро бармегардонад. Он як усули ягона дорад - apply
(кор кардан).
- Мо истеъмолкунанда дорем (
Consumer
), ки A -ро қабул мекунад ва ҳеҷ чизро барнамегардонад ( Void ). Он танҳо як усул дорад - accept
(қабул).
- Мо code дорем, ки дар ришта кор мекунад
Runnable
, ки онро қабул намекунад ё барнагардонад. Он як усули ягона дорад - run
(давидан).
Чизи дуюми дар хотир доштан дар он аст, ки дар кори худ истеъмолкунандагон ва функсияҳоро
CompletalbeFuture
истифода мебарад .
Runnable
Бо назардошти ин, шумо ҳамеша метавонед дар хотир доред, ки шумо
CompletableFuture
ин корро карда метавонед:
public static void main(String []args) throws Exception {
AtomicLong longValue = new AtomicLong(0);
Runnable task = () -> longValue.set(new Date().getTime());
Function<Long, Date> dateConverter = (longvalue) -> new Date(longvalue);
Consumer<Date> printer = date -> {
System.out.println(date);
System.out.flush();
};
CompletableFuture.runAsync(task)
.thenApply((v) -> longValue.get())
.thenApply(dateConverter)
.thenAccept(printer);
}
Усулҳо versionҳо
thenRun
доранд . _ Ин маънои онро дорад, ки ин марҳилаҳо дар риштаи нав иҷро карда мешаванд. Он аз ҳавзи махсус гирифта мешавад, бинобар ин пешакӣ маълум нест, ки он чӣ гуна ҷараён аст, нав ё кӯҳна. Ҳамааш ба он вобаста аст, ки вазифаҳо то чӣ андоза душворанд. Илова ба ин усулҳо, боз се имконоти ҷолиб вуҷуд доранд. Барои равшанӣ, биёед тасаввур кунем, ки мо хидмати муайяне дорем, ки аз ҷое паём қабул мекунад ва ин вақтро мегирад:
thenApply
thenAccept
Async
public static class NewsService {
public static String getMessage() {
try {
Thread.currentThread().sleep(3000);
return "Message";
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}
Акнун биёед ба дигар хусусиятҳои он назар андозем
CompletableFuture
. Мо метавонем натиҷаро
CompletableFuture
бо натиҷаи дигаре якҷоя кунем
CompletableFuture
:
Supplier newsSupplier = () -> NewsService.getMessage();
CompletableFuture<String> reader = CompletableFuture.supplyAsync(newsSupplier);
CompletableFuture.completedFuture("!!")
.thenCombine(reader, (a, b) -> b + a)
.thenAccept(result -> System.out.println(result))
.get();
Бояд қайд кард, ки ба таври нобаёнӣ риштаҳо риштаҳои демонӣ хоҳанд буд, аз ин рӯ барои возеҳӣ
get
мо интизори натиҷаро истифода мебарем. Ва мо метавонем на танҳо якҷоя кунем (якҷоя кунем), балки боз баргардем
CompletableFuture
:
CompletableFuture.completedFuture(2L)
.thenCompose((val) -> CompletableFuture.completedFuture(val + 2))
.thenAccept(result -> System.out.println(result));
Дар ин ҷо ман мехоҳам қайд намоям, ки барои кӯтоҳ, усул истифода шудааст
CompletableFuture.completedFuture
. Ин усул риштаи нав эҷод намекунад, бинобар ин қисми боқимондаи занҷир дар ҳамон риштае, ки дар он номида шуда буд, иҷро карда мешавад
completedFuture
. Усул ҳам ҳаст
thenAcceptBoth
. Он ба - хеле монанд аст
accept
, аммо агар
thenAccept
-ро қабул кунад
consumer
,
thenAcceptBoth
он гоҳ дигар
CompletableStage
+ -ро ҳамчун вуруд қабул мекунад
BiConsumer
, яъне
consumer
2 манбаъро ҳамчун вуруд қабул мекунад, на як. Боз як имкони ҷолиб бо калима вуҷуд дорад
Either
:
Ин усулҳо алтернативаро қабул мекунанд ва дар ҳамон усуле , ки аввал иҷро мешавад,
CompletableStage
иҷро карда мешаванд .
CompletableStage
Ва ман мехоҳам ин баррасиро бо як хусусияти ҷолиби дигар
CompletableFuture
- коркарди хато анҷом диҳам.
CompletableFuture.completedFuture(2L)
.thenApply((a) -> {
throw new IllegalStateException("error");
}).thenApply((a) -> 3L)
.thenAccept(val -> System.out.println(val));
Ин code ҳеҷ коре намекунад, зеро... истисно партофта мешавад ва ҳеҷ чиз рӯй нахоҳад дод. Аммо агар мо шарҳ надиҳем
exceptionally
, мо рафторро муайян мекунем.
CompletableFuture
Ман инчунин тавсия медиҳам, ки видеои зеринро дар ин мавзӯъ тамошо кунед:
Ба андешаи хоксоронаи ман, ин видеоҳо аз ҳама визуалӣ дар Интернет мебошанд. Аз онҳо бояд равшан бошад, ки ин ҳама чӣ гуна кор мекунад, мо чӣ арсенал дорем ва чаро ин ҳама лозим аст.
Хулоса
Умедворам, ки ҳоло маълум аст, ки чӣ гуна риштаҳоро барои дарёфти ҳисобҳо пас аз ҳисоб кардани онҳо истифода бурдан мумкин аст. Маводи иловагӣ:
#Вячеслав
GO TO FULL VERSION