Outils pour utilisateurs

Outils du site


lang:java:thread

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:java:thread [2019/09/30 09:24] – Ajout d'une source rootlang:java:thread [2023/06/12 15:07] (Version actuelle) – Ajout de "Nommage des threads" root
Ligne 1: Ligne 1:
-=====Threads=====+=====Différentes classes=====
 ====Runnable==== ====Runnable====
  
Ligne 28: Ligne 28:
 </code> </code>
  
-====Méthodes courantes==== +====FutureTask====
-  * ''void start()'' : éligibilité +
-  * ''void run()'' : instructions du Thread +
-  * ''void interrupt()'' : arrêt programmé +
-  * ''boolean interrupted()'' : thread arrêté ? +
-  * ''void stop()'' : déprécié au profit de ''interrupt()'' +
-  * ''static void sleep(long ms)'' : arrêt pendant un certain temps +
-  * ''static native Thread currentThread()''+
  
 +Une ''FutureTask'' doit renvoyer un type. Mettre ''Void'' et ''return null'' si le type de retour n'est pas utilisé.
 +
 +''FutureTask'' s'exécute depuis un ''Executor'' et la valeur de retour est récupérée via la méthode bloquante ''get''.
 +
 +Quand une exception est générée, elle n'est pas remontée au thread principale. Elle est transformée en une ''ExecutionException'' qui sera générée lors de l'appel à ''get''.
 +
 +<code java>
 +import java.util.concurrent.FutureTask;
 +import java.io.IOException;
 +import java.util.concurrent.ExecutorService;
 +import java.util.concurrent.Executors;
 +import java.util.concurrent.ExecutionException;
 +
 +public class MyClass {
 +  public static void main(String args[]) {
 +    FutureTask<Void> futureTask = new FutureTask<Void> (() -> {
 +      throw new IOException("OUPS");
 +    });
 +    ExecutorService executor = Executors.newFixedThreadPool(2);
 +    executor.execute(futureTask);
 +    try {
 +      futureTask.get();
 +    } catch (InterruptedException e) {
 +    } catch (ExecutionException e) {
 +      e.printStackTrace();
 +    }
 +    System.out.println("OK");
 +    System.out.println("OK2");
 +    executor.shutdown();
 +  }
 +}
 +</code>
 +
 +Sortie standard :
 +
 +<code>
 +OK
 +OK2
 +
 +java.util.concurrent.ExecutionException: java.io.IOException: OUPS
 + at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
 + at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
 + at MyClass.main(MyClass.java:15)
 +Caused by: java.io.IOException: OUPS
 + at MyClass.lambda$main$0(MyClass.java:10)
 + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
 + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
 + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 + at java.base/java.lang.Thread.run(Thread.java:833)
 +</code>
 +
 +Si l'exception doit être remontée au thread principale, il faut créer une classe qui hérite de ''FutureTask'' et surchargée la méthode ''done()'', appeler le ''get()'' avec le try/catch associé et générer une autre exception (''AssertionError'' par exemple).
 +
 +<code java>
 +import java.io.IOException;
 +import java.util.concurrent.Callable;
 +import java.util.concurrent.ExecutionException;
 +import java.util.concurrent.ExecutorService;
 +import java.util.concurrent.Executors;
 +import java.util.concurrent.FutureTask;
 +
 +public class MyClass {
 +  public static class SecuredFutureTask<V> extends FutureTask<V> {
 +    public SecuredFutureTask(Callable<V> callable) {
 +      super(callable);
 +    }
 +
 +    @Override
 +    protected void done() {
 +      try {
 +        get();
 +      } catch (ExecutionException | InterruptedException e) {
 +        throw new AssertionError(e);
 +      }
 +    }
 +  }
 +  public static void main(String args[]) {
 +    FutureTask<Void> futureTask =
 +        new SecuredFutureTask<Void>(() -> { throw new IOException("OUPS"); });
 +    ExecutorService executor = Executors.newFixedThreadPool(2);
 +    executor.execute(futureTask);
 +    System.out.println("OK");
 +    executor.shutdown();
 +  }
 +}
 +</code>
 +
 +Sortie standard :
 +
 +<code>
 +OK
 +
 +Exception in thread "pool-1-thread-1" java.lang.AssertionError: java.util.concurrent.ExecutionException: java.io.IOException: OUPS
 + at MyClass$SecuredFutureTask.done(MyClass.java:19)
 + at java.base/java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:381)
 + at java.base/java.util.concurrent.FutureTask.setException(FutureTask.java:250)
 + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:269)
 + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
 + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 + at java.base/java.lang.Thread.run(Thread.java:833)
 +Caused by: java.util.concurrent.ExecutionException: java.io.IOException: OUPS
 + at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
 + at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
 + at MyClass$SecuredFutureTask.done(MyClass.java:17)
 + ... 6 more
 +Caused by: java.io.IOException: OUPS
 + at MyClass.lambda$main$0(MyClass.java:25)
 + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
 + ... 3 more
 +</code>
 =====Accès concurrent===== =====Accès concurrent=====
 <code java> <code java>
Ligne 58: Ligne 161:
  
 [[https://www.ibm.com/developerworks/java/tutorials/j-concur/j-concur.html|Concurrency in JDK 5.0]] {{ :lang:java:thread:concurrency_in_jdk_5.0_2019-09-30_08_49_25_.html |Archive au 30/09/2019, version du 23/11/2004}} [[https://www.ibm.com/developerworks/java/tutorials/j-concur/j-concur.html|Concurrency in JDK 5.0]] {{ :lang:java:thread:concurrency_in_jdk_5.0_2019-09-30_08_49_25_.html |Archive au 30/09/2019, version du 23/11/2004}}
 +
 +======Barrières=====
 +
 +====Semaphore====
 +
 +Barrière en attente d'un signal.
 +
 +<code java>
 +import java.util.concurrent.Semaphore;
 +
 +public class MyClass {
 +  public static void main(String args[]) {
 +    Semaphore semaphoreAcquisitionReady = new Semaphore(0);
 +
 +    new Thread(() -> {
 +      try {
 +        Thread.sleep(50);
 +      } catch (InterruptedException e) {}
 +      System.out.println("BEFORE release");
 +      semaphoreAcquisitionReady.release();
 +      System.out.println("AFTER release");
 +    }).start();
 +
 +    System.out.println("BEFORE acquire");
 +    try {
 +      semaphoreAcquisitionReady.acquire();
 +    } catch (InterruptedException e) {}
 +    System.out.println("AFTER acquire");
 +
 +    semaphoreAcquisitionReady.release();
 +  }
 +}
 +</code>
 +
 +Sortie standard.
 +
 +<code>
 +BEFORE acquire
 +BEFORE release
 +AFTER release
 +AFTER acquire
 +</code>
 +
 +=====Debug=====
 +====Nommage des threads====
 +
 +Par défaut, le nom d'un thread est ''Thread-0'' / ''Thread-1''. Si le thread tourne dans un pool : ''pool-1-thread-1''.
 +
 +Dans le cas des threads, cela se fait directement depuis le constructeur.
 +
 +<code java>
 +new Thread(() -> {}, "Nom du thread").start();
 +</code>
 +
 +Dans le cas de ''Runnable'' qui se lancent dans un pool de threads, il faut modifier le nom directement dans la méthode exécutée par le thread.
 +
 +<code java>
 +new FutureTask<>(() -> {
 +  Thread.currentThread().setName("Nom du thread");
 +});
 +</code>
lang/java/thread.1569828297.txt.gz · Dernière modification : 2019/09/30 09:24 de root