JavaRush /Java Blog /Random-TK /Java-ny sapak bilen zaýalap bilmersiňiz: IV bölüm - Çagyr...
Viacheslav
Dereje

Java-ny sapak bilen zaýalap bilmersiňiz: IV bölüm - Çagyrylýan, Geljek we dostlar

Toparda çap edildi

Giriş

Birinji bölümde sapaklaryň nähili döredilendigine eýýäm göz aýladyk . Againene bir gezek ýatlalyň. Java-ny sapak bilen zaýalap bilmersiňiz: IV bölüm - Jaň edip boljak, Geljek we dostlar - 1Bir sapak Threadiç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, Runnabletäze interfeýsiň tersine, callnetijä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? RunnableIndi 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. FutureOny 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, getproblemadan 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 @FunctionalInterfacewe 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 taskgeljekde biziňkiler ýerine ýetiriler we getnetijä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ň: Java-ny sapak bilen zaýalap bilmersiňiz: IV bölüm - Jaň edip boljak, Geljek we dostlar - 2Ine, olary ulanmagyň wariantlary:
import java.util.concurrent.CompletableFuture;
public class App {
    public static void main(String []args) throws Exception {
        // CompletableFuture уже содержащий результат
        CompletableFuture<String> completed;
        completed = CompletableFuture.completedFuture("Просто meaning");
        // CompletableFuture, запускающий (run) новый поток с Runnable, поэтому он Void
        CompletableFuture<Void> voidCompletableFuture;
        voidCompletableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("run " + Thread.currentThread().getName());
        });
        // CompletableFuture, запускающий новый поток, результат которого возьмём у Supplier
        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 CompletableFuturehasaplanan 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 FunctionA alyp, B-ni yzyna gaýtaryp berýän bir funksiýa bar, onuň ýekeje usuly bar - apply(ulanyň).
  • ConsumerBizde A-ny kabul edýän we hiç zat yzyna gaýtarmaýan sarp ediji bar . Onuň diňe bir usuly bar - accept(kabul et).
  • RunnableBizde 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, CompletalbeFutureişinde Runnablesarp 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 computation
        CompletableFuture.runAsync(task)
                         .thenApply((v) -> longValue.get())
                         .thenApply(dateConverter)
                         .thenAccept(printer);
}
Usullaryň wersiýalary thenRunbar . _ 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: thenApplythenAcceptAsync
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 CompletableFuturebaş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 getnetijä 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 thenAcceptkabul edýän bolsa consumer, başga bir + giriş hökmünde thenAcceptBothkabul 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 . CompletableStageBiConsumerconsumerEitherJava-ny sapak bilen zaýalap bilmersiňiz: IV bölüm - Jaň edip boljak, Geljek we dostlar - 3CompletableStageCompletableStageCompletableFuture
CompletableFuture.completedFuture(2L)
				 .thenApply((a) -> {
					throw new IllegalStateException("error");
				 }).thenApply((a) -> 3L)
				 //.exceptionally(ex -> 0L)
				 .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 CompletableFutureaş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
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION