bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


futurs_java

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

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_java_exemple.zip |}}
  
 ==== Futurs ==== ==== Futurs ====
Línia 19: Línia 21:
  
  
-En realitat es fan amb fils paral·lels, però la implementació ens allibera de definir-los un a un+En realitat es fan amb fils paral·lels (threads), però la implementació ens allibera de definir-los un a un
  
  
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 System.currentTimeMillis(); +public class EsperaSegonsCalcul { 
-  double segons = (finish start/ 1000.0+    private ExecutorService executor Executors.newSingleThreadExecutor(); 
-  System.out.println("Esperant ... " + segons + " segons");+   
 +    public Future<Integer> calculate(Integer input) {         
 +        return executor.submit(() -> { 
 +            long millis = (new Random()).nextInt(3000) + 1000
 +            System.out.println("Trigarà: " + (millis / 1000.0) + " milisegons"); 
 +            Thread.sleep(millis); 
 +            return input * input; 
 +        }); 
 +    }
  
-  if (segons > 2) { +    public void shutdown () { executor.shutdown(); } 
-    // Si esperem més de 2 segons, ja no volem el resultat +}
-    future.cancel(true); +
-  }+
  
-  try +</code> 
-    Thread.sleep(300); + 
-  } catch (InterruptedException e) { e.printStackTrace(); }+<code java> 
 +import java.util.concurrent.ExecutionException; 
 +import java.util.concurrent.Future; 
 + 
 +public class EsperaSegonsMain 
 +    public static void main(String args[]) { 
 +        EsperaSegonsCalcul obj = new EsperaSegonsCalcul(); 
 +        Future<Integer> future = obj.calculate(7); 
 +        long start = System.currentTimeMillis(); 
 +        long finish = 0; 
 + 
 +        while (!future.isDone()) { 
 +            finish = System.currentTimeMillis(); 
 +            double segons = (finish - start) / 1000.0; 
 +            System.out.println("Esperant ... " + segons + " segons"); 
 +            if (segons > 2) { 
 +                // Si esperem més de 2 segons, ja no volem el resultat 
 +                future.cancel(true); 
 +            } 
 +            try { 
 +                Thread.sleep(300); 
 +            } catch (InterruptedException e) { e.printStackTrace(); } 
 +        } 
 + 
 +        try { 
 +            if (future.isCancelled()) { 
 +                System.out.println("El resultat ha trigat massa"); 
 +            } else { 
 +                Integer result = future.get(); 
 +                System.out.println("Resultat: " + result); 
 +            } 
 +            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:
  
 </code> </code>
 +
 +==== 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 "ReentrantLock", tal i com mostra el següent exemple.
 +
 +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<CompletableFuture<Void>> futureList = new ArrayList<>();
 +        for (int cnt = 0; cnt < 5; cnt++){
 +            futureList.add(CompletableFuture.runAsync((getRunnable(cnt))));
 +        }
 +
 +        // Execucio dels futurs
 +        System.out.println("Esperant resultats");
 +        futureList.forEach(CompletableFuture::join); 
 +
 +        // Mostrar resultats
 +        System.out.println("Resultats:");
 +        System.out.println("Dades sense bloqueig: " + dadesSns);
 +        System.out.println("Dades amb bloqueig: " + dadesBqg);
 +    }
 +
 +    //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();
 +                }
 +            }
 +        };
 +    }
 +}
 +</code>
 +
 +
futurs_java.1669217775.txt.gz · Darrera modificació: 2022/11/23 15:36 per albert_palacios_jimenez