Giriş
Birinji bölümde sapaklaryň nähili döredilendigine eýýäm göz aýladyk . Againene bir gezek ýatlalyň.
Bir sapak
Thread
içindäki bir zat
run
, şonuň üçin geliň,
“java” onlaýn kompilýatoryny ulanalyň we aşakdaky kody ýerine ýetireliň:
public class HelloWorld {
public static void main(String []args){
Runnable task = () -> {
System.out.println("Hello World");
};
new Thread(task).start();
}
}
Bir meseläni sapakda işletmek üçin bu ýeke-täk mümkinçilikmi?
java.util.concurrent.Callable
Görnüşi ýaly,
java.lang.Runnable-iň dogany bar we ady
java.util.concurrent.Callable we Java 1.5-de doguldy. Tapawutlar näme? Bu interfeýsiň JavaDoc-a has içgin göz aýlasak,
Runnable
täze interfeýsiň tersine,
call
netijäni berýän usuly yglan edýändigini görýäris. Mundan başga-da, kadadan çykma. Checkagny, barlanan kadadan çykmalar üçin blok ýazmak zerurlygyndan halas edýär
try-catch
. Erbet däl, şeýlemi?
Runnable
Indi onuň ýerine täze bir wezipe bar :
Callable task = () -> {
return "Hello, World!";
};
Emma munuň bilen näme etmeli? Näme üçin hatda netijäni berýän sapakda işleýän bir mesele gerek? Elbetde, geljekde ýerine ýetiriljek hereketleriň netijesini alarys. Iňlis dilinde geljek - Geljek. Edil şol bir at bilen interfeýs bar:
java.util.concurrent.Future
java.util.concurrent.Future
Java.util.concurrent.Future interfeýsi geljekde almagy meýilleşdirýän meseleler bilen işlemek üçin API-ni suratlandyrýar: netijeleri almagyň usullary, ýagdaýy barlamagyň usullary.
Future
Ony durmuşa geçirmek
java.util.concurrent.FutureTask bilen gyzyklanýarys . .Agny
Task
, ýerine ýetiriljek zat şu
Future
. Bu ýerine ýetirişde gyzykly zat, durmuşa geçirmegi we
Runnable
. Muňa sapaklardaky meseleler bilen işlemegiň köne modeliniň we täze modeliň (java 1.5-de peýda bolandygy manysynda täze) adapter diýip hasaplap bilersiňiz. Ine bir mysal:
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());
}
}
Mysaldan görnüşi ýaly, usuldan peýdalanyp,
get
problemadan netijäni alýarys
task
.
(!) Möhümusuly ulanyp netijäniň alnan pursatynda
get
ýerine ýetiriş sinhron bolýar. Siziň pikiriňizçe bu ýerde haýsy mehanizm ulanylar? Dogry, sinhronizasiýa bloky ýok - şonuň üçin JVisualVM-de
garaşmagymonitor
göreris ýa-da däl
wait
-de, şol bir
park
(mehanizm ulanylýandygy sebäpli
LockSupport
).
Funksiýa interfeýsleri
Geljekde Java 1.8-den sapaklar barada gürleşeris, şonuň üçin gysgaça tanyşlyk etmek peýdaly bolardy. Aşakdaky koda seredeliň:
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);
}
};
Gereksiz kod köp, şeýlemi? Jarnamada yglan edilen synplaryň her biri ýekeje funksiýany ýerine ýetirýär, ýöne muny beýan etmek üçin bir topar gereksiz kömekçi kod ulanýarys. Java döredijiler hem şeýle pikir etdiler. Şol sebäpden, “funksional interfeýsler” () toplumyny hödürlediler
@FunctionalInterface
we indi Java-yň özi möhümlerden başga hemme zady “oýlanjak” diýen karara geldiler:
Supplier<String> supplier = () -> "String";
Consumer<String> consumer = s -> System.out.println(s);
Function<String, Integer> converter = s -> Integer.valueOf(s);
Supplier
- üpjün ediji. Parametrleri ýok, ýöne bir zady yzyna berýär, ýagny üpjün edýär.
Consumer
- sarp ediji. Giriş (parametrler) hökmünde bir zat alýar we onuň bilen bir zat edýär, ýagny bir zady sarp edýär. Başga bir funksiýa bar. Giriş (parametr) hökmünde bir zat alýar
s
, bir zat edýär we bir zady yzyna berýär. Görşümiz ýaly, generikler işjeň ulanylýar. Ynanmasaňyz, olary ýatda saklap, “
Java-da generika teoriýasy ýa-da garniturany nädip ulanmalydygyny ” okap bilersiňiz.
CompletableFuture
Wagtyň geçmegi bilen Java 1.8 atly täze synp hödürledi
CompletableFuture
. Interfeýsi ýerine ýetirýär
Future
, ýagny
task
geljekde biziňkiler ýerine ýetiriler we
get
netijäni ýerine ýetirip bileris. Alsoöne käbirlerini durmuşa geçirýär
CompletionStage
. Terjimeden onuň maksady eýýäm düşnükli: haýsydyr bir hasaplamanyň belli bir tapgyry. Mowzuk bilen gysgaça tanyşlygy "
CompletionStage we CompletableFuture " -iň umumy synyndan tapyp bilersiňiz. Geliň, göni düşüneliň. Başlamaga kömek etmek üçin elýeterli statiki usullaryň sanawyna seredeliň:
Ine, olary ulanmagyň wariantlary:
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 "Значение";
});
}
}
Bu kody işledenimizde, döredijiligiň
CompletableFuture
ähli zynjyry başlamagy göz öňünde tutýandygyny göreris. Şonuň üçin Java8-den SteamAPI bilen birneme meňzeşlik bar bolsa, bu çemeleşmeleriň arasyndaky tapawut. Mysal üçin:
List<String> array = Arrays.asList("one", "two");
Stream<String> stringStream = array.stream().map(value -> {
System.out.println("Executed");
return value.toUpperCase();
});
Bu Java 8 Stream Api-iň mysaly (bu hakda has giňişleýin maglumaty şu ýerde "
Suratlar we mysallardaky Java 8 Stream API gollanmasy "). Bu kody işledseňiz, görkezilmez
Executed
. Javaagny, Java-da akym döredilende akym derrew başlamaz, ýöne ondan bir baha gerek bolýança garaşýar. Emma
CompletableFuture
hasaplanan bahanyň soralmagyna garaşman, derrew ýerine ýetirmek üçin zynjyry başlaýar. Muňa düşünmek möhümdir diýip pikir edýärin. Şeýlelik bilen bizde “CompletableFuture” bar. Zynjyry nädip döredip bileris we nämäni aňladýar? Öň ýazan funksional interfeýslerimizi ýada salalyň.
- Bizde
Function
A alyp, B-ni yzyna gaýtaryp berýän bir funksiýa bar, onuň ýekeje usuly bar - apply
(ulanyň).
Consumer
Bizde A-ny kabul edýän we hiç zat yzyna gaýtarmaýan sarp ediji bar . Onuň diňe bir usuly bar - accept
(kabul et).
Runnable
Bizde kabul etmeýän ýa-da gaýdyp gelmeýän sapakda işleýän kod bar . Onuň ýekeje usuly bar - run
(işletmek).
Rememberatda saklamaly ikinji zat,
CompletalbeFuture
işinde
Runnable
sarp edijileri we funksiýalary ulanýar. Şuny göz öňünde tutup, muny edip biljekdigiňizi hemişe ýadyňyzdan çykaryp bilersiňiz
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);
}
Usullaryň wersiýalary
thenRun
bar . _ Bu, bu etaplaryň täze sapakda ýerine ýetiriljekdigini aňladýar. Specialörite howuzdan alynar, şonuň üçin täze ýa-da köne haýsy akymyň boljakdygy öňünden belli däl. Bularyň hemmesi wezipeleriň näderejede kyndygyna baglydyr. Bu usullardan başga-da üç sany gyzykly mümkinçilik bar. Has düşnükli bolmak üçin, bir ýerden habar alýan belli bir hyzmatyň bardygyny göz öňüne getireliň we wagt gerek:
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);
}
}
}
Indi, beýleki aýratynlyklara seredeliň
CompletableFuture
. Netijäni
CompletableFuture
başga biriniň netijesi bilen birleşdirip bileris
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();
Adaty tertipde sapaklaryň daemon sapaklary boljakdygyny bellemelidiris, aýdyňlyk üçin
get
netijä garaşmak üçin ulanýarys. Diňe birleşdirip (birleşdirip) däl, eýsem gaýdyp bileris
CompletableFuture
:
CompletableFuture.completedFuture(2L)
.thenCompose((val) -> CompletableFuture.completedFuture(val + 2))
.thenAccept(result -> System.out.println(result));
Bu ýerde gysga wagtlyk bu usulyň ulanylandygyny belläsim gelýär
CompletableFuture.completedFuture
. Bu usul täze sapak döredenok, şonuň üçin zynjyryň galan bölegi atlandyrylan sapakda ýerine ýetiriler
completedFuture
. Şeýle hem bir usul bar
thenAcceptBoth
. Örän meňzeýär
accept
, ýöne
thenAccept
kabul edýän bolsa
consumer
, başga bir + giriş hökmünde
thenAcceptBoth
kabul edýär , ýagny 2 çeşmäni bir däl-de giriş hökmünde kabul edýär. Söz bilen başga bir gyzykly mümkinçilik bar : Bu usullar alternatiwany kabul edýär we ilki ýerine ýetirilen usulda ýerine ýetiriler . Bu syny başga bir gyzykly aýratynlyk - ýalňyşlyk bilen işlemek bilen tamamlamak isleýärin .
CompletableStage
BiConsumer
consumer
Either
CompletableStage
CompletableStage
CompletableFuture
CompletableFuture.completedFuture(2L)
.thenApply((a) -> {
throw new IllegalStateException("error");
}).thenApply((a) -> 3L)
.thenAccept(val -> System.out.println(val));
Bu kod hiç zat etmez, sebäbi ... kadadan çykma taşlanar we hiç zat bolmaz. Weöne başarnyksyz bolsak
exceptionally
, özüni alyp barşymyzy kesgitleýäris. Şeýle hem şu mowzukda
CompletableFuture
aşakdaky wideo görmegi maslahat berýärin :
Pespäl pikirimçe, bu wideolar internetde iň görnükli. Bularyň nähili işleýändigi, haýsy arsenalymyz bar we näme üçin zerurdygy olardan düşnükli bolmaly.
Netije
Hasaplar hasaplanandan soň almak üçin sapaklaryň nädip ulanylyp bilinjekdigi indi düşnükli diýip umyt edýärin. Goşmaça material:
# Wiaçeslaw
GO TO FULL VERSION