簡體   English   中英

Java多線程:檢查第一個線程的返回值后,使線程啟動

[英]Java Multi-threading: make a thread to start after checking the returned value from the first thread

我有一個基本上與服務器建立連接的線程,如果連接成功,它將返回一個正ID號。 我想創建另一個線程,該線程將檢查當前ID號是否為正,並在檢測到ID為正時運行。

// 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();

請注意, obj.getCurrentId()返回當前ID號。 但是我正在努力編寫第二個線程以及它如何與第一個線程通信。 有人可以幫我嗎? 謝謝。

假定您使用Java 8是實現它的一種好方法,因為CompletableFuture可以使您定義要執行的異步任務流。

因此,例如,這里的主要代碼可能是:

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

MyClass的方法connect可以是:

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;
}

MyClass someMethodAsync方法可以是:

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

MyClass類的someMethod方法可以是:

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

另一種方法可能是依靠wait / notify / notifyAllawait / signal / signalAll來通知另一個線程id已更改。

因此您的代碼可能是這樣的:

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();
            }
        }
    }
}

因此,您的第一個線程將簡單地調用makeConnection()makeConnection()是它內部調用了SomeClass的setter setCurrentId ,第二個線程將通過調用waitForPositiveId()使其開始,直到id為正為止。

注意:如果makeConnection()失敗,此方法將使第二個線程永遠等待。

我建議使用ExecutorServiceCallable接口-只是返回你的身份證號碼Future結果。

看看ExecutorService.html#submit

幾點建議:

  1. 創建一個ExecutorService
  2. 提交第一個任務: ConnectionTask並獲取結果
  3. 提交第二個任務: ValidationTask並獲得結果
  4. 根據結果​​,您可以執行下一組操作。

樣例代碼:

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;
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM