2016-10-19 2 views
0

Ich habe einen Thread, der im Grunde eine Verbindung zum Server herstellt und wenn die Verbindung erfolgreich ist, wird es eine positive ID-Nummer zurückgeben. Ich möchte einen anderen Thread erstellen, der überprüft, ob die aktuelle ID-Nummer positiv ist und ausgeführt wird, sobald er feststellt, dass die ID positiv ist.Java Multithreading: einen Thread nach dem Überprüfen des zurückgegebenen Wertes aus dem ersten Thread zu starten

// My first thread that establishes connection 

new Thread() { 
    public void run(){ 
      makeConnection(); 
      // this makeConnection method will make the ID become a positive number if the connection is fully established. 
    } 
}.start(); 

Beachten Sie, dass obj.getCurrentId() die aktuelle ID-Nummer zurückgibt. Aber ich kämpfe darum, den zweiten Thread zu schreiben und wie er mit dem ersten Thread kommuniziert. Kann mir bitte jemand helfen? Vielen Dank.

+3

So wollen Sie die Verbindung verwenden, erst nach dem Herstellen der Verbindung erfolgreich ist. Warum nicht einen Thread für beides verwenden? Threads sind für gleichzeitige Aufgaben. –

+0

Weil es Zeit braucht, um tatsächlich eine Verbindung zum Server herzustellen und damit die ID positiv wird. Wenn ich beide Aufgaben unter einem Thread zusammenführe, befürchte ich, dass der Code "überprüfe, ob die ID positiv ist" ausgeführt wird, wenn die vollständige Verbindung noch nicht vollständig hergestellt ist. – user1769197

+1

Warum also zwei Threads lösen dieses Problem. Wenn Sie einen Thread verwenden, wissen Sie zumindest, dass Sie die Verbindung erst verwenden können, wenn makeConnection() zurückgegeben wurde. –

Antwort

0

Ich empfehle die Verwendung ExecutorService mit Callable Schnittstelle - geben Sie einfach Ihre ID-Nummer in Future Ergebnis.

Werfen Sie einen Blick auf ExecutorService.html#submit

1

, dass Sie Java 8 ein guter Weg, es ist mit CompletableFuture zu implementieren verwenden Unter der Annahme, da es einen Fluss von asynchronen Aufgaben zu definieren, ermöglicht es auszuführen.

So zum Beispiel hier der Hauptcode könnte sein:

// Call connect asynchronously using the common pool from a given thread 
// then execute someMethod using another thread 
CompletableFuture.supplyAsync(MyClass::connect) 
    .thenCompose(MyClass::someMethodAsync); 

Verfahren connect der Klasse MyClass sein könnte:

public static int connect() { 
    try { 
     SomeClass obj = makeConnection(); 
     // ok so we return a positive value 
     return obj.getCurrentId(); 
    } catch (Exception e) { 
     // Do something here 
    } 
    // ko so we return a negative value 
    return -1; 
} 

Verfahren someMethodAsync der Klasse MyClass könnte sein:

public static CompletionStage<Void> someMethodAsync(int id) { 
    return CompletableFuture.supplyAsync(() -> MyClass.someMethod(id)); 
} 

Die Methode someMethod der Klasse MyClass könnte sein:

public static Void someMethod(int id) { 
    if (id > 0) { 
     // do something 
    } 
    return null; 
} 

Ein weiterer Ansatz könnte auf wait/notify/notifyAll oder await/signal/signalAll verlassen, um den anderen Thread zu benachrichtigen, dass die id geändert hat.

So könnte Ihr Code so ähnlich sein:

public class SomeClass { 
    /** 
    * The current id 
    */ 
    private int currentId; 
    /** 
    * The object's monitor 
    */ 
    private final Object monitor = new Object(); 

    /** 
    * @return the current id 
    */ 
    public int getCurrentId() { 
     synchronized (monitor) { 
      return this.currentId; 
     } 
    } 

    /** 
    * Sets the current id and notifies waiting threads 
    */ 
    public void setCurrentId(final int currentId) { 
     synchronized (monitor) { 
      this.currentId = currentId; 
      monitor.notifyAll(); 
     } 
    } 

    /** 
    * Makes the calling thread wait until the id is positive 
    * @throws InterruptedException if current thread is interrupted while waiting 
    */ 
    public void waitForPositiveId() throws InterruptedException { 
     synchronized (monitor) { 
      while (currentId <= 0) { 
       monitor.wait(); 
      } 
     } 
    } 
} 

So Ihre erste Thread wird makeConnection() rufen Sie einfach an, dass intern vorausgesetzt, es ist die Setter setCurrentId von SomeClass und den zweiten Thread von waitForPositiveId() Aufruf startet ruft zu machen warte bis die ID positiv ist.

Hinweis: Dieser Ansatz wird den zweiten Thread für immer warten lassen, wenn makeConnection() fehlschlägt.

0

paar Vorschläge:

  1. Neues ExecutorService
  2. die erste Aufgabe einreichen: ConnectionTask und erhalten das Ergebnis
  3. die zweite Aufgabe einreichen: ValidationTask und erhalten das Ergebnis
  4. auf das Ergebnis je Sie kann die nächsten Aktionen ausführen.

Beispielcode:

import java.util.concurrent.*; 
import java.util.*; 

public class CallablePollingDemo{ 
    public CallablePollingDemo(){ 
     System.out.println("creating service"); 
     ExecutorService service = Executors.newFixedThreadPool(2);  
     try{ 
      Future future1 = service.submit(new ConnectionTask()); 
      int result1 = ((Integer)future1.get()).intValue(); 
      System.out.println("Result from ConnectionTask task:"+result1); 
      if (result1 > 0){ // change this condition to suit your requirement 
       Future future2 = service.submit(new ValidationTask(result1)); 
       int result2 = ((Integer)future2.get()).intValue(); 
       System.out.println("Result from ValidationTask task:"+result2); 
      } 

     }catch(Exception err){ 
      err.printStackTrace(); 
     } 
     service.shutdown(); 
    } 
    public static void main(String args[]){ 
     CallablePollingDemo demo = new CallablePollingDemo(); 
    } 
    class ConnectionTask implements Callable<Integer>{ 

     public ConnectionTask(){ 

     } 
     public Integer call(){ 
      int id = 1; 
      // Add your business logic here , make connection, get the result 
      return id; 
     } 
    } 
    class ValidationTask implements Callable<Integer>{ 
     Integer id = 0; 
     public ValidationTask(Integer val){ 
      this.id = val; 
     } 
     public Integer call(){ 
      // Add your verification result ehre 
      if (id > 0) { 
       return id; 
      }else{ 
       return -1; 
      } 
     } 
    } 
} 
Verwandte Themen