{"id":3138,"date":"2022-06-15T05:27:58","date_gmt":"2022-06-15T05:27:58","guid":{"rendered":"http:\/\/the-codest.localhost\/blog\/concurrency-in-java-part-1-introduction\/"},"modified":"2026-03-11T05:59:41","modified_gmt":"2026-03-11T05:59:41","slug":"wspolbieznosc-w-java-czesc-1-wprowadzenie","status":"publish","type":"post","link":"https:\/\/thecodest.co\/pl\/blog\/concurrency-in-java-part-1-introduction\/","title":{"rendered":"Wsp\u00f3\u0142bie\u017cno\u015b\u0107 w Javie Cz\u0119\u015b\u0107 1 - Wprowadzenie"},"content":{"rendered":"<p>Og\u00f3lnie rzecz bior\u0105c, konwencjonalne podej\u015bcie do programowania jest sekwencyjne. Wszystko w programie dzieje si\u0119 krok po kroku.<br>Ale w rzeczywisto\u015bci r\u00f3wnoleg\u0142o\u015b\u0107 jest sposobem, w jaki dzia\u0142a ca\u0142y \u015bwiat - jest to zdolno\u015b\u0107 do wykonywania wi\u0119cej ni\u017c jednego zadania jednocze\u015bnie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">W\u0105tek a proces<\/h2>\n\n\n\n<p>Om\u00f3wienie takich zaawansowanych temat\u00f3w jak <strong>wsp\u00f3\u0142bie\u017cno\u015b\u0107 w <a href=\"https:\/\/thecodest.co\/pl\/blog\/top-programming-languages-to-build-e-commerce\/\">Java<\/a><\/strong> lub wielow\u0105tkowo\u015b\u0107, musimy ustali\u0107 pewne wsp\u00f3lne definicje, aby mie\u0107 pewno\u015b\u0107, \u017ce jeste\u015bmy po tej samej stronie.<\/p>\n\n\n\n<p>Zacznijmy od podstaw. W niesekwencyjnym \u015bwiecie, mamy dwa rodzaje reprezentant\u00f3w wsp\u00f3\u0142bie\u017cno\u015bci: procesy oraz<br>w\u0105tki. Proces to instancja uruchomionego programu. Zazwyczaj jest on odizolowany od innych proces\u00f3w.<br>System operacyjny jest odpowiedzialny za przypisywanie zasob\u00f3w do ka\u017cdego procesu. Ponadto dzia\u0142a jako przewodnik, kt\u00f3ry<br>harmonogramy i kontroluje je.<\/p>\n\n\n\n<p>W\u0105tek jest rodzajem procesu, ale na ni\u017cszym poziomie, dlatego jest r\u00f3wnie\u017c znany jako lekki w\u0105tek. Wiele w\u0105tk\u00f3w mo\u017ce dzia\u0142a\u0107 w jednym<br>proces. W tym przypadku program dzia\u0142a jako harmonogram i kontroler w\u0105tk\u00f3w. W ten spos\u00f3b poszczeg\u00f3lne programy wydaj\u0105 si\u0119 wykonywa\u0107<br>wiele zada\u0144 w tym samym czasie.<\/p>\n\n\n\n<p>Podstawow\u0105 r\u00f3\u017cnic\u0105 mi\u0119dzy w\u0105tkami a procesami jest poziom izolacji. Proces ma sw\u00f3j w\u0142asny zestaw<br>zasob\u00f3w, podczas gdy w\u0105tek wsp\u00f3\u0142dzieli <a href=\"https:\/\/thecodest.co\/pl\/blog\/app-data-collection-security-risks-value-and-types-explored\/\">dane<\/a> z innymi w\u0105tkami. Mo\u017ce si\u0119 to wydawa\u0107 podej\u015bciem podatnym na b\u0142\u0119dy i rzeczywi\u015bcie tak jest. Dla<br>Nie skupiajmy si\u0119 teraz na tym, poniewa\u017c wykracza to poza zakres tego artyku\u0142u.<\/p>\n\n\n\n<p>Procesy, w\u0105tki - ok... Ale czym dok\u0142adnie jest wsp\u00f3\u0142bie\u017cno\u015b\u0107? Wsp\u00f3\u0142bie\u017cno\u015b\u0107 oznacza mo\u017cliwo\u015b\u0107 wykonywania wielu zada\u0144 jednocze\u015bnie.<br>czasu. Nie oznacza to, \u017ce zadania te musz\u0105 by\u0107 wykonywane jednocze\u015bnie - na tym polega r\u00f3wnoleg\u0142o\u015b\u0107. <strong>Concurrenc w Javay<\/strong> r\u00f3wnie\u017c nie<br>wymaga posiadania wielu procesor\u00f3w lub nawet wielu rdzeni. Mo\u017cna to osi\u0105gn\u0105\u0107 w \u015brodowisku jednordzeniowym, wykorzystuj\u0105c<br>prze\u0142\u0105czanie kontekstu.<\/p>\n\n\n\n<p>Termin zwi\u0105zany ze wsp\u00f3\u0142bie\u017cno\u015bci\u0105 to wielow\u0105tkowo\u015b\u0107. Jest to cecha program\u00f3w, kt\u00f3ra pozwala im wykonywa\u0107 kilka zada\u0144 jednocze\u015bnie. Nie ka\u017cdy program korzysta z tego podej\u015bcia, ale te, kt\u00f3re to robi\u0105, mo\u017cna nazwa\u0107 wielow\u0105tkowymi.<\/p>\n\n\n\n<p>Jeste\u015bmy prawie gotowi, jeszcze tylko jedna definicja. Asynchronia oznacza, \u017ce program wykonuje operacje bez blokowania.<br>Inicjuje zadanie, a nast\u0119pnie wykonuje inne czynno\u015bci w oczekiwaniu na odpowied\u017a. Kiedy otrzyma odpowied\u017a, mo\u017ce <a href=\"https:\/\/thecodest.co\/pl\/blog\/react-development-all-you-have-to-know\/\">reagowa\u0107<\/a> do niego.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ca\u0142y ten jazz<\/h2>\n\n\n\n<p>Domy\u015blnie ka\u017cdy <strong>Aplikacja Java<\/strong> dzia\u0142a w jednym procesie. W procesie tym istnieje jeden w\u0105tek zwi\u0105zany z aplikacj\u0105 <code>main()<\/code> metoda<br>aplikacji. Jak jednak wspomniano, mo\u017cliwe jest wykorzystanie mechanizm\u00f3w wielow\u0105tkowo\u015bci w ramach jednej aplikacji.<br>program.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wykonywalny<\/h3>\n\n\n\n<p><code>W\u0105tek<\/code> jest <strong>Java<\/strong> w kt\u00f3rej dzieje si\u0119 magia. Jest to reprezentacja obiektowa wcze\u015bniej wspomnianego w\u0105tku. Do<br>utworzy\u0107 w\u0142asny w\u0105tek, mo\u017cna rozszerzy\u0107 <code>W\u0105tek<\/code> klasa. Nie jest to jednak zalecane podej\u015bcie. <code>Nici<\/code> powinien by\u0107 u\u017cywany jako mechanizm uruchamiaj\u0105cy zadanie. Zadania s\u0105 elementami <a href=\"https:\/\/thecodest.co\/pl\/dictionary\/what-is-code-refactoring\/\">kod<\/a> kt\u00f3re chcemy uruchomi\u0107 w trybie wsp\u00f3\u0142bie\u017cnym. Mo\u017cemy je zdefiniowa\u0107 za pomoc\u0105 funkcji <code>Wykonywalny<\/code> interfejs.<\/p>\n\n\n\n<p>Ale do\u015b\u0107 teorii, w\u0142\u00f3\u017cmy nasz kod tam, gdzie s\u0105 nasze usta.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Problem<\/h3>\n\n\n\n<p>Za\u0142\u00f3\u017cmy, \u017ce mamy kilka tablic liczb. Dla ka\u017cdej tablicy chcemy pozna\u0107 sum\u0119 liczb w tablicy. Za\u0142\u00f3\u017cmy<br>Za\u0142\u00f3\u017cmy, \u017ce takich tablic jest wiele i ka\u017cda z nich jest stosunkowo du\u017ca. W takich warunkach chcemy wykorzysta\u0107 wsp\u00f3\u0142bie\u017cno\u015b\u0107 i zsumowa\u0107 ka\u017cd\u0105 tablic\u0119 jako osobne zadanie.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">int[] a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\nint[] a2 = {10, 10, 10, 10, 10, 10, 10, 10};;\nint[] a3 = {3, 4, 3, 4, 3, 4, 2, 1, 3, 7};\n\nRunnable task1 = () -&gt; {\n    int sum = Arrays.stream(a1).sum();\n    System.out.println(\"1. Suma wynosi: \" + sum);\n};\n\nRunnable task2 = () -&gt; {\n    int sum = Arrays.stream(a2).sum();\n    System.out.println(\"2. Suma wynosi: \" + sum);\n};\n\nRunnable task3 = () -&gt; {\n    int sum = Arrays.stream(a3).sum();\n    System.out.println(\"3. Suma wynosi: \" + sum);\n};\n\nnew Thread(task1).start();\nnew Thread(task2).start();\nnew Thread(task3).start();<\/code><\/pre>\n\n\n\n<p>Jak wida\u0107 z powy\u017cszego kodu <code>Wykonywalny<\/code> jest interfejsem funkcjonalnym. Zawiera jedn\u0105 abstrakcyjn\u0105 metod\u0119 <code>run()<\/code><br>bez argument\u00f3w. The <code>Wykonywalny<\/code> Interfejs powinien by\u0107 implementowany przez ka\u017cd\u0105 klas\u0119, kt\u00f3rej instancje maj\u0105 by\u0107<br>wykonywane przez w\u0105tek.<\/p>\n\n\n\n<p>Po zdefiniowaniu zadania mo\u017cna utworzy\u0107 w\u0105tek do jego uruchomienia. Mo\u017cna to osi\u0105gn\u0105\u0107 poprzez <code>new Thread()<\/code> konstruktor, kt\u00f3ry<br>bierze <code>Wykonywalny<\/code> jako argument.<\/p>\n\n\n\n<p>Ostatnim krokiem jest <code>start()<\/code> nowo utworzony w\u0105tek. W <a href=\"https:\/\/thecodest.co\/pl\/blog\/compare-staff-augmentation-firms-that-excel-in-api-team-staffing-for-financial-technology-projects\/\">API<\/a> s\u0105 r\u00f3wnie\u017c <code>run()<\/code> metody w <code>Wykonywalny<\/code> oraz w<br><code>W\u0105tek<\/code>. Nie jest to jednak spos\u00f3b na wykorzystanie wsp\u00f3\u0142bie\u017cno\u015bci w Javie. Bezpo\u015brednie wywo\u0142anie ka\u017cdej z tych metod skutkuje<br>wykonanie zadania w tym samym w\u0105tku <code>main()<\/code> metoda dzia\u0142a.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pule w\u0105tk\u00f3w i executorzy<\/h3>\n\n\n\n<p>W przypadku du\u017cej liczby zada\u0144 tworzenie osobnego w\u0105tku dla ka\u017cdego z nich nie jest dobrym pomys\u0142em. Tworzenie w\u0105tku <code>W\u0105tek<\/code> jest<br>i znacznie lepiej jest ponownie wykorzysta\u0107 istniej\u0105ce w\u0105tki ni\u017c tworzy\u0107 nowe.<\/p>\n\n\n\n<p>Gdy program tworzy wiele kr\u00f3tkotrwa\u0142ych w\u0105tk\u00f3w, lepiej jest u\u017cy\u0107 puli w\u0105tk\u00f3w. Pula w\u0105tk\u00f3w zawiera pewn\u0105 liczb\u0119<br>gotowych do uruchomienia, ale obecnie nieaktywnych w\u0105tk\u00f3w. Daj\u0105c <code>Wykonywalny<\/code> do puli powoduje, \u017ce jeden z w\u0105tk\u00f3w wywo\u0142uje funkcj\u0119<br><code>run()<\/code> metoda danego <code>Wykonywalny<\/code>. Po zako\u0144czeniu zadania w\u0105tek nadal istnieje i znajduje si\u0119 w stanie bezczynno\u015bci.<\/p>\n\n\n\n<p>Ok, jasne - wolisz pul\u0119 w\u0105tk\u00f3w zamiast r\u0119cznego tworzenia. Ale jak mo\u017cna wykorzysta\u0107 pule w\u0105tk\u00f3w? The <code>Wykonawcy<\/code><br>posiada szereg statycznych metod fabrycznych do konstruowania pul w\u0105tk\u00f3w. Na przyk\u0142ad <code>newCachedThredPool()<\/code> tworzy<br>pula, w kt\u00f3rej nowe w\u0105tki s\u0105 tworzone w razie potrzeby, a bezczynne w\u0105tki s\u0105 przechowywane przez 60 sekund. W przeciwie\u0144stwie do tego,<br><code>newFixedThreadPool()<\/code> zawiera sta\u0142y zestaw w\u0105tk\u00f3w, w kt\u00f3rym bezczynne w\u0105tki s\u0105 przechowywane w niesko\u0144czono\u015b\u0107.<\/p>\n\n\n\n<p>Zobaczmy, jak to mo\u017ce dzia\u0142a\u0107 w naszym przyk\u0142adzie. Teraz nie musimy tworzy\u0107 w\u0105tk\u00f3w r\u0119cznie. Zamiast tego musimy utworzy\u0107<br><code>ExecutorService<\/code> kt\u00f3ra zapewnia pul\u0119 w\u0105tk\u00f3w. Nast\u0119pnie mo\u017cemy przypisa\u0107 do niego zadania. Ostatnim krokiem jest zamkni\u0119cie w\u0105tku<br>aby unikn\u0105\u0107 wyciek\u00f3w pami\u0119ci. Reszta poprzedniego kodu pozostaje bez zmian.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">ExecutorService executor = Executors.newCachedThreadPool();\n\nexecutor.submit(task1);\nexecutor.submit(task2);\nexecutor.submit(task3);\n\nexecutor.shutdown();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Na \u017c\u0105danie<\/h3>\n\n\n\n<p><code>Wykonywalny<\/code> wydaje si\u0119 fajnym sposobem na tworzenie wsp\u00f3\u0142bie\u017cnych zada\u0144, ale ma jedn\u0105 powa\u017cn\u0105 wad\u0119. Nie mo\u017ce zwr\u00f3ci\u0107 \u017cadnego<br>warto\u015b\u0107. Co wi\u0119cej, nie mo\u017cemy okre\u015bli\u0107, czy zadanie zosta\u0142o uko\u0144czone, czy nie. Nie wiemy te\u017c, czy zosta\u0142o ono uko\u0144czone<br>normalnie lub wyj\u0105tkowo. Rozwi\u0105zaniem tych bol\u0105czek jest <code>Na \u017c\u0105danie<\/code>.<\/p>\n\n\n\n<p><code>Na \u017c\u0105danie<\/code> jest podobny do <code>Wykonywalny<\/code> w pewnym sensie r\u00f3wnie\u017c opakowuje zadania asynchroniczne. G\u0142\u00f3wn\u0105 r\u00f3\u017cnic\u0105 jest to, \u017ce jest w stanie<br>zwraca warto\u015b\u0107. Zwracana warto\u015b\u0107 mo\u017ce by\u0107 dowolnego (nieprymitywnego) typu, tak jak funkcja <code>Na \u017c\u0105danie<\/code> jest typem sparametryzowanym.<br><code>Na \u017c\u0105danie<\/code> jest funkcjonalnym interfejsem, kt\u00f3ry posiada <code>call()<\/code> kt\u00f3ra mo\u017ce rzuci\u0107 metod\u0119 <code>Wyj\u0105tek<\/code>.<\/p>\n\n\n\n<p>Zobaczmy teraz, jak mo\u017cemy wykorzysta\u0107 <code>Na \u017c\u0105danie<\/code> w naszym problemie z tablic\u0105.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">int[] a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\nint[] a2 = {10, 10, 10, 10, 10, 10, 10, 10};;\nint[] a3 = {3, 4, 3, 4, 3, 4, 2, 1, 3, 7};\n\nCallable task1 = () -&gt; Arrays.stream(a1).sum();\nCallable task2 = () -&gt; Arrays.stream(a2).sum();\nCallable task3 = () -&gt; Arrays.stream(a3).sum();\n\nExecutorService executor = Executors.newCachedThreadPool();\nFuture future1 = executor.submit(task1);\nFuture future2 = executor.submit(task2);\nFuture future3 = executor.submit(task3);\n\nSystem.out.println(\"1. Suma wynosi: \" + future1.get());\nSystem.out.println(\"2. Suma wynosi: \" + future2.get());\nSystem.out.println(\"3. Suma wynosi: \" + future3.get());\n\nexecutor.shutdown();<\/code><\/pre>\n\n\n\n<p>Ok, mo\u017cemy zobaczy\u0107 jak <code>Na \u017c\u0105danie<\/code> jest tworzony, a nast\u0119pnie przesy\u0142any do <code>ExecutorService<\/code>. Ale czym do cholery jest <code>Przysz\u0142o\u015b\u0107<\/code>?<br><code>Przysz\u0142o\u015b\u0107<\/code> dzia\u0142a jako pomost mi\u0119dzy w\u0105tkami. Suma ka\u017cdej tablicy jest tworzona w oddzielnym w\u0105tku i potrzebujemy sposobu na<br>otrzymanie tych wynik\u00f3w z powrotem do <code>main()<\/code>.<\/p>\n\n\n\n<p>Aby pobra\u0107 wynik z <code>Przysz\u0142o\u015b\u0107<\/code> musimy zadzwoni\u0107 <code>get()<\/code> metoda. Tutaj mo\u017ce wydarzy\u0107 si\u0119 jedna z dw\u00f3ch rzeczy. Po pierwsze<br>wynik oblicze\u0144 wykonanych przez <code>Na \u017c\u0105danie<\/code> jest dost\u0119pny. Wtedy otrzymujemy go natychmiast. Po drugie, wynik nie jest<br>jeszcze gotowy. W takim przypadku <code>get()<\/code> b\u0119dzie blokowana do momentu uzyskania wyniku.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ComputableFuture<\/h3>\n\n\n\n<p>Problem z <code>Przysz\u0142o\u015b\u0107<\/code> jest to, \u017ce dzia\u0142a w \"paradygmacie push\". Podczas korzystania z <code>Przysz\u0142o\u015b\u0107<\/code> musisz by\u0107 jak szef, kt\u00f3ry<br>nieustannie pyta: \"Czy zadanie zosta\u0142o wykonane? Czy jest gotowe?\", dop\u00f3ki nie przyniesie rezultatu. Dzia\u0142anie pod ci\u0105g\u0142\u0105 presj\u0105 to<br>drogie. O wiele lepszym podej\u015bciem by\u0142oby zam\u00f3wienie <code>Przysz\u0142o\u015b\u0107<\/code> co zrobi\u0107, gdy b\u0119dzie gotowy do wykonania swojego zadania. Niestety,<br><code>Przysz\u0142o\u015b\u0107<\/code> nie mo\u017ce tego zrobi\u0107, ale <code>ComputableFuture<\/code> mo\u017ce.<\/p>\n\n\n\n<p><code>ComputableFuture<\/code> dzia\u0142a w paradygmacie \"pull\". Mo\u017cemy mu powiedzie\u0107, co ma zrobi\u0107 z wynikiem, gdy wykona swoje zadania. To<br>jest przyk\u0142adem podej\u015bcia asynchronicznego.<\/p>\n\n\n\n<p><code>ComputableFuture<\/code> dzia\u0142a idealnie z <code>Wykonywalny<\/code> ale nie z <code>Na \u017c\u0105danie<\/code>. Zamiast tego mo\u017cliwe jest dostarczenie zadania do<br><code>ComputableFuture<\/code> w postaci <code>Dostawca<\/code>.<\/p>\n\n\n\n<p>Zobaczmy, jak powy\u017csze odnosi si\u0119 do naszego problemu.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">int[] a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\nint[] a2 = {10, 10, 10, 10, 10, 10, 10, 10};;\nint[] a3 = {3, 4, 3, 4, 3, 4, 2, 1, 3, 7};\n\nCompletableFuture.supplyAsync(() -&gt; Arrays.stream(a1).sum())\n                .thenAccept(System.out::println);\n\nCompletableFuture.supplyAsync(() -&gt; Arrays.stream(a2).sum())\n                .thenAccept(System.out::println);\n\nCompletableFuture.supplyAsync(() -&gt; Arrays.stream(a3).sum())\n                .thenAccept(System.out::println);<\/code><\/pre>\n\n\n\n<p>Pierwsz\u0105 rzecz\u0105, kt\u00f3ra rzuca si\u0119 w oczy, jest to, o ile kr\u00f3tsze jest to rozwi\u0105zanie. Poza tym wygl\u0105da schludnie i estetycznie.<\/p>\n\n\n\n<p>Zadanie do <code>CompletableFuture<\/code> mog\u0105 by\u0107 dostarczane przez <code>supplyAsync()<\/code> metoda, kt\u00f3ra przyjmuje <code>Dostawca<\/code> lub przez <code>runAsync()<\/code> \u017ce<br>bierze <code>Wykonywalny<\/code>. Wywo\u0142anie zwrotne - fragment kodu, kt\u00f3ry powinien zosta\u0107 uruchomiony po zako\u0144czeniu zadania - jest definiowane przez <code>thenAccept()<\/code><br>metoda.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wnioski<\/h2>\n\n\n\n<p><strong>Java<\/strong> zapewnia wiele r\u00f3\u017cnych podej\u015b\u0107 do wsp\u00f3\u0142bie\u017cno\u015bci. W tym artykule ledwie dotkn\u0119li\u015bmy tego tematu.<\/p>\n\n\n\n<p>Niemniej jednak, om\u00f3wili\u015bmy podstawy <code>W\u0105tek<\/code>, <code>Wykonywalny<\/code>, <code>Na \u017c\u0105danie<\/code>oraz <code>CallableFuture<\/code> co stanowi dobry punkt<br>do dalszego badania tematu.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/thecodest.co\/contact\/\"><img loading=\"lazy\" decoding=\"async\" width=\"1283\" height=\"460\" src=\"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_.png\" alt=\"\" class=\"wp-image-4927\" srcset=\"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_.png 1283w, https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_-300x108.png 300w, https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_-1024x367.png 1024w, https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_-768x275.png 768w, https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_-18x6.png 18w, https:\/\/thecodest.co\/app\/uploads\/2024\/05\/interested_in_cooperation_-67x24.png 67w\" sizes=\"auto, (max-width: 1283px) 100vw, 1283px\" \/><\/a><\/figure>","protected":false},"excerpt":{"rendered":"<p>Przeczytaj pierwsz\u0105 cz\u0119\u015b\u0107 naszej serii blog\u00f3w po\u015bwi\u0119conych wsp\u00f3\u0142bie\u017cno\u015bci w Javie. W kolejnym artykule przyjrzymy si\u0119 bli\u017cej r\u00f3\u017cnicom mi\u0119dzy w\u0105tkami i procesami, pulom w\u0105tk\u00f3w, executorom i wielu innym!<\/p>","protected":false},"author":2,"featured_media":3139,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-3138","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Concurrency in Java Part 1 - Introduction - The Codest<\/title>\n<meta name=\"description\" content=\"Read the first part of our blog series devoted to concurrency in Java.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thecodest.co\/pl\/blog\/wspolbieznosc-w-java-czesc-1-wprowadzenie\/\" \/>\n<meta property=\"og:locale\" content=\"pl_PL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Concurrency in Java Part 1 - Introduction\" \/>\n<meta property=\"og:description\" content=\"Read the first part of our blog series devoted to concurrency in Java.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thecodest.co\/pl\/blog\/wspolbieznosc-w-java-czesc-1-wprowadzenie\/\" \/>\n<meta property=\"og:site_name\" content=\"The Codest\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-15T05:27:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-11T05:59:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/concurrency_in_java_part_1_-_introduction.png\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"thecodest\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"thecodest\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minut\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/\"},\"author\":{\"name\":\"thecodest\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\"},\"headline\":\"Concurrency in Java Part 1 &#8211; Introduction\",\"datePublished\":\"2022-06-15T05:27:58+00:00\",\"dateModified\":\"2026-03-11T05:59:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/\"},\"wordCount\":1295,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/concurrency_in_java_part_1_-_introduction.png\",\"articleSection\":[\"Software Development\"],\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/\",\"name\":\"Concurrency in Java Part 1 - Introduction - The Codest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/concurrency_in_java_part_1_-_introduction.png\",\"datePublished\":\"2022-06-15T05:27:58+00:00\",\"dateModified\":\"2026-03-11T05:59:41+00:00\",\"description\":\"Read the first part of our blog series devoted to concurrency in Java.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#breadcrumb\"},\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#primaryimage\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/concurrency_in_java_part_1_-_introduction.png\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/concurrency_in_java_part_1_-_introduction.png\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/concurrency-in-java-part-1-introduction\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/thecodest.co\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Concurrency in Java Part 1 &#8211; Introduction\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"name\":\"The Codest\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/thecodest.co\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pl-PL\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\",\"name\":\"The Codest\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"width\":144,\"height\":36,\"caption\":\"The Codest\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/pl.linkedin.com\\\/company\\\/codest\",\"https:\\\/\\\/clutch.co\\\/profile\\\/codest\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\",\"name\":\"thecodest\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"caption\":\"thecodest\"},\"url\":\"https:\\\/\\\/thecodest.co\\\/pl\\\/author\\\/thecodest\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Wsp\u00f3\u0142bie\u017cno\u015b\u0107 w Javie Cz\u0119\u015b\u0107 1 - Wprowadzenie - The Codest","description":"Przeczytaj pierwsz\u0105 cz\u0119\u015b\u0107 naszej serii blog\u00f3w po\u015bwi\u0119conych wsp\u00f3\u0142bie\u017cno\u015bci w Javie.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/thecodest.co\/pl\/blog\/wspolbieznosc-w-java-czesc-1-wprowadzenie\/","og_locale":"pl_PL","og_type":"article","og_title":"Concurrency in Java Part 1 - Introduction","og_description":"Read the first part of our blog series devoted to concurrency in Java.","og_url":"https:\/\/thecodest.co\/pl\/blog\/wspolbieznosc-w-java-czesc-1-wprowadzenie\/","og_site_name":"The Codest","article_published_time":"2022-06-15T05:27:58+00:00","article_modified_time":"2026-03-11T05:59:41+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/concurrency_in_java_part_1_-_introduction.png","type":"image\/png"}],"author":"thecodest","twitter_card":"summary_large_image","twitter_misc":{"Written by":"thecodest","Est. reading time":"6 minut"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#article","isPartOf":{"@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/"},"author":{"name":"thecodest","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76"},"headline":"Concurrency in Java Part 1 &#8211; Introduction","datePublished":"2022-06-15T05:27:58+00:00","dateModified":"2026-03-11T05:59:41+00:00","mainEntityOfPage":{"@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/"},"wordCount":1295,"commentCount":0,"publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"image":{"@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/concurrency_in_java_part_1_-_introduction.png","articleSection":["Software Development"],"inLanguage":"pl-PL","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/","url":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/","name":"Wsp\u00f3\u0142bie\u017cno\u015b\u0107 w Javie Cz\u0119\u015b\u0107 1 - Wprowadzenie - The Codest","isPartOf":{"@id":"https:\/\/thecodest.co\/#website"},"primaryImageOfPage":{"@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#primaryimage"},"image":{"@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/concurrency_in_java_part_1_-_introduction.png","datePublished":"2022-06-15T05:27:58+00:00","dateModified":"2026-03-11T05:59:41+00:00","description":"Przeczytaj pierwsz\u0105 cz\u0119\u015b\u0107 naszej serii blog\u00f3w po\u015bwi\u0119conych wsp\u00f3\u0142bie\u017cno\u015bci w Javie.","breadcrumb":{"@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#breadcrumb"},"inLanguage":"pl-PL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/"]}]},{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#primaryimage","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/concurrency_in_java_part_1_-_introduction.png","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/concurrency_in_java_part_1_-_introduction.png","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/thecodest.co\/blog\/concurrency-in-java-part-1-introduction\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/thecodest.co\/"},{"@type":"ListItem","position":2,"name":"Concurrency in Java Part 1 &#8211; Introduction"}]},{"@type":"WebSite","@id":"https:\/\/thecodest.co\/#website","url":"https:\/\/thecodest.co\/","name":"The Codest","description":"","publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thecodest.co\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pl-PL"},{"@type":"Organization","@id":"https:\/\/thecodest.co\/#organization","name":"The Codest","url":"https:\/\/thecodest.co\/","logo":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","width":144,"height":36,"caption":"The Codest"},"image":{"@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/pl.linkedin.com\/company\/codest","https:\/\/clutch.co\/profile\/codest"]},{"@type":"Person","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76","name":"thecodest","image":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","caption":"thecodest"},"url":"https:\/\/thecodest.co\/pl\/author\/thecodest\/"}]}},"_links":{"self":[{"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/posts\/3138","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/comments?post=3138"}],"version-history":[{"count":8,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/posts\/3138\/revisions"}],"predecessor-version":[{"id":8551,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/posts\/3138\/revisions\/8551"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/media\/3139"}],"wp:attachment":[{"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/media?parent=3138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/categories?post=3138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecodest.co\/pl\/wp-json\/wp\/v2\/tags?post=3138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}