我有一个基本上与服务器建立连接的线程,如果连接成功,它将返回一个正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号。但我正在努力编写第二个线程以及它如何与第一个线程进行通信。有人可以帮帮我吗?感谢。
答案 0 :(得分:1)
假设您使用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);
班级connect
的方法MyClass
可以是:
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;
}
班级someMethodAsync
的方法MyClass
可以是:
public static CompletionStage<Void> someMethodAsync(int id) {
return CompletableFuture.supplyAsync(() -> MyClass.someMethod(id));
}
班级someMethod
的方法MyClass
可以是:
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()
,假设它在内部调用setCurrentId
的setter SomeClass
,第二个线程将通过调用waitForPositiveId()
来启动它以使其等待直到id为正。
NB:如果makeConnection()
失败,此方法将使第二个线程等待。
答案 1 :(得分:0)
我建议将ExecutorService
与Callable
界面一起使用 - 只需在Future
结果中返回您的ID号。
答案 2 :(得分:0)
很少有建议:
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;
}
}
}
}