-1

I have a method which currently needs to return a result to the client no slower than it currently is. So it must call a method and forget about it, it should continue processing and not wait for that method to return any result. I have been playing around with ejb @Asynchronous annotation and also using new Threads. I found the following:

Way 1: Using @Asynchronous - When this method is called, the caller seems to wait. This method returns void so i thought that the caller would call it and move on but not so. Caller Code:

public static void main(String[] args) {
    System.out.println("Caller Starting");
    Processor p = new Processor();
    p.doSomeStuff();
    System.out.println("Caller Ended");
}

public class Processor{
@Asynchronous
public void doSomeStuff() {
    System.out.println("Async start");
    for(int i = 0; i < 50; i++) {
        System.out.println("Async: " +i);
    }
    System.out.println("Async ended");
}

}

Way 2: Using new Thread - When i do it this way, it does what i want it to do.

public static void main(String[] args) {
    System.out.println("Caller Starting");
    Processor p = new Processor();
    p.doSomeStuff();
    System.out.println("Caller Ended");
}

@Stateless

public class Processor extends Thread{

public void doSomeStuff() {
    start();        
}

@Override
public void run() {

    // Loop for ten iterations.

    for(int i=0; i<10; i++) {
        System.out.println(i + " looping ...");

        // Sleep for a while
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // Interrupted exception will occur if
            // the Worker object's interrupt() method
            // is called. interrupt() is inherited
            // from the Thread class.
            break;
        }
    }
}

Am i using the @Asynchronous annotation incorrectly?
What would be a good solution for this requirement? Is there a better simpler way to meet the requirements?

Ken
  • 127
  • 2
  • 11

1 Answers1

1

Use the @Asynchronous annotation does the same thing as when creating a new thread but with less hassle. In your case, you have been using the annotation incorrectly. The asynchronous method must be in a Stateless bean for it to run without the caller method waiting. So probably this should work,

@Stateless
public class Processor{
@Asynchronous
public void doSomeStuff() {
    System.out.println("Async start");
    for(int i = 0; i < 50; i++) {
        System.out.println("Async: " +i);
    }
    System.out.println("Async ended");
}
Pragya
  • 101
  • 4
  • Thanks, let me fix up adding the @Stateless annotation, though im fairly sure i started of that way, but will do again. I am also trying out CompleteableFuture, using the runAsync method specifically. I think it does the same, but with less code/plumbing. – Ken Jul 16 '19 at 14:00