[英]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
/ notifyAll
或await
/ 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()
失敗,此方法將使第二個線程永遠等待。
我建議使用ExecutorService
與Callable
接口-只是返回你的身份證號碼Future
結果。
幾點建議:
ConnectionTask
並獲取結果 ValidationTask
並獲得結果 樣例代碼:
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.