Reputation: 2213
I have a thread that basically makes a connection to the server and if the connection is successful, it will return a positive ID number. I would like to create another thread that will check if the current ID number is positive and runs once it detects the ID is positive.
// 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();
Note that obj.getCurrentId()
returns the current ID number. But I am struggling to write the second thread and how it communicates with the first thread. Can someone kindly help me out please? Thanks.
Upvotes: 0
Views: 95
Reputation: 2597
I recommend using ExecutorService
with Callable
interface - just return your ID number in Future
result.
Have a look at ExecutorService.html#submit
Upvotes: 0
Reputation: 38910
Few suggestions:
ConnectionTask
and get the resultValidationTask
and get the resultSample code:
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;
}
}
}
}
Upvotes: 0
Reputation: 44965
Assuming that you use Java 8
a good way to implement it is with CompletableFuture
as it will allow you to define a flow of asynchronous tasks to execute.
So for example here the main code could be:
// Call connect asynchronously using the common pool from a given thread
// then execute someMethod using another thread
CompletableFuture.supplyAsync(MyClass::connect)
.thenCompose(MyClass::someMethodAsync);
The method connect
of the class MyClass
could be:
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;
}
The method someMethodAsync
of the class MyClass
could be:
public static CompletionStage<Void> someMethodAsync(int id) {
return CompletableFuture.supplyAsync(() -> MyClass.someMethod(id));
}
The method someMethod
of the class MyClass
could be:
public static Void someMethod(int id) {
if (id > 0) {
// do something
}
return null;
}
Another approach could be to rely on wait
/notify
/notifyAll
or await
/signal
/signalAll
to notify the other thread that the id
has changed.
So your code could be something like that:
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 your first thread will simply call makeConnection()
assuming that internally it calls the setter setCurrentId
of SomeClass
and the second thread will start by calling waitForPositiveId()
to make it wait until the id is positive.
NB: This approach will make the second thread wait for ever if makeConnection()
fails.
Upvotes: 1