Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| Següent revisió | Revisió prèvia | ||
|
futurs_java [2022/11/23 15:36] albert_palacios_jimenez creat |
futurs_java [2022/12/16 10:43] (actual) albert_palacios_jimenez |
||
|---|---|---|---|
| Línia 1: | Línia 1: | ||
| - | |||
| ====== Futurs a Java ====== | ====== Futurs a Java ====== | ||
| Línia 7: | Línia 6: | ||
| ---- | ---- | ||
| + | ==== Exemples ==== | ||
| + | |||
| + | {{ :: | ||
| ==== Futurs ==== | ==== Futurs ==== | ||
| Línia 19: | Línia 21: | ||
| - | En realitat es fan amb fils paral·lels, | + | En realitat es fan amb fils paral·lels |
| Línia 100: | Línia 102: | ||
| <code java> | <code java> | ||
| - | while(!future.isDone()) { | + | import java.util.Random; |
| + | import java.util.concurrent.ExecutorService; | ||
| + | import java.util.concurrent.Executors; | ||
| + | import java.util.concurrent.Future; | ||
| - | finish | + | public class EsperaSegonsCalcul { |
| - | | + | private ExecutorService executor |
| - | System.out.println(" | + | |
| + | public Future< | ||
| + | return executor.submit(() | ||
| + | long millis = (new Random()).nextInt(3000) + 1000; | ||
| + | System.out.println(" | ||
| + | Thread.sleep(millis); | ||
| + | return input * input; | ||
| + | }); | ||
| + | } | ||
| - | if (segons > 2) { | + | public void shutdown |
| - | // Si esperem més de 2 segons, ja no volem el resultat | + | } |
| - | future.cancel(true); | + | |
| - | } | + | |
| - | try { | + | </ |
| - | Thread.sleep(300); | + | |
| - | } catch (InterruptedException e) { e.printStackTrace(); | + | <code java> |
| + | import java.util.concurrent.ExecutionException; | ||
| + | import java.util.concurrent.Future; | ||
| + | |||
| + | public class EsperaSegonsMain | ||
| + | | ||
| + | EsperaSegonsCalcul obj = new EsperaSegonsCalcul(); | ||
| + | Future< | ||
| + | long start = System.currentTimeMillis(); | ||
| + | long finish = 0; | ||
| + | |||
| + | while (!future.isDone()) { | ||
| + | finish = System.currentTimeMillis(); | ||
| + | double segons = (finish - start) / 1000.0; | ||
| + | System.out.println(" | ||
| + | if (segons > 2) { | ||
| + | // Si esperem més de 2 segons, ja no volem el resultat | ||
| + | future.cancel(true); | ||
| + | } | ||
| + | try { | ||
| + | | ||
| + | } catch (InterruptedException e) { e.printStackTrace(); | ||
| + | } | ||
| + | |||
| + | try { | ||
| + | if (future.isCancelled()) { | ||
| + | System.out.println(" | ||
| + | } else { | ||
| + | Integer result = future.get(); | ||
| + | System.out.println(" | ||
| + | } | ||
| + | obj.shutdown(); | ||
| + | } catch (InterruptedException e) { e.printStackTrace(); | ||
| + | } catch (ExecutionException e) { e.printStackTrace(); | ||
| + | } | ||
| } | } | ||
| Línia 194: | Línia 239: | ||
| **.runAsync** quan no tenen valor de retorn | **.runAsync** quan no tenen valor de retorn | ||
| + | |||
| **.supplyAsync** quan tenen valor de retorn | **.supplyAsync** quan tenen valor de retorn | ||
| Línia 349: | Línia 395: | ||
| </ | </ | ||
| + | |||
| + | ==== CompletableFuture i dades compartides ==== | ||
| + | |||
| + | Cada futur en realitat és un thread que es pot executar en paral·lel a altres futurs. | ||
| + | |||
| + | Si aquests futurs accedeixen a les mateixes dades, s’ha de tenir algun mètode de bloqueig, per tal que els altres threads no modifiquin les dades simultàniament i per tant aquestes siguin errònies. | ||
| + | |||
| + | Aquest bloqueig es pot aconseguir amb " | ||
| + | |||
| + | En aquest codi es veu com les dades sense bloqueig només poden comptar fins a 10 perquè els fils es trepitgen entre ells, però les que implementen el bloqueig aconsegueixen comptar fins a 50. | ||
| + | |||
| + | <code java> | ||
| + | import java.util.ArrayList; | ||
| + | import java.util.concurrent.CompletableFuture; | ||
| + | import java.util.concurrent.locks.ReentrantLock; | ||
| + | |||
| + | public class FutMain { | ||
| + | |||
| + | // Vector de dades | ||
| + | private static int dadesSns = 0; | ||
| + | private static int dadesBqg = 0; | ||
| + | |||
| + | // Bloquejador de recursos | ||
| + | private static ReentrantLock mutex = new ReentrantLock(); | ||
| + | |||
| + | // Main | ||
| + | public static void main(String[] args) { | ||
| + | | ||
| + | // Creacio de futurs | ||
| + | ArrayList< | ||
| + | for (int cnt = 0; cnt < 5; cnt++){ | ||
| + | futureList.add(CompletableFuture.runAsync((getRunnable(cnt)))); | ||
| + | } | ||
| + | |||
| + | // Execucio dels futurs | ||
| + | System.out.println(" | ||
| + | futureList.forEach(CompletableFuture:: | ||
| + | |||
| + | // Mostrar resultats | ||
| + | System.out.println(" | ||
| + | System.out.println(" | ||
| + | System.out.println(" | ||
| + | } | ||
| + | |||
| + | //Codi executat pels futurs | ||
| + | static Runnable getRunnable (int pos) { | ||
| + | return new Runnable () { | ||
| + | @Override public void run () { | ||
| + | |||
| + | // Modificar les dades sense bloqueig | ||
| + | for (int cnt = 0; cnt < 10; cnt++) { | ||
| + | int val = dadesSns; | ||
| + | try {Thread.sleep(10); | ||
| + | catch (InterruptedException e) {e.printStackTrace(); | ||
| + | dadesSns = val + 1; | ||
| + | } | ||
| + | |||
| + | try { | ||
| + | // Bloquejem els recursos per assegurar la seva exclusivitat | ||
| + | mutex.lock(); | ||
| + | |||
| + | // Modificar les dades amb bloqueig | ||
| + | for (int cnt = 0; cnt < 10; cnt++) { | ||
| + | int val = dadesBqg; | ||
| + | try {Thread.sleep(10); | ||
| + | catch (InterruptedException e) {e.printStackTrace(); | ||
| + | dadesBqg = val + 1; | ||
| + | } | ||
| + | |||
| + | } finally { | ||
| + | mutex.unlock(); | ||
| + | } | ||
| + | } | ||
| + | }; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||