[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 386
  • Last Modified:

how to make this function async?

i have a java function

public String somefunc
{
minifunc();

//i want the function to return a string after minifunc2() to whatever is calling it.  BUT still finish executing 3 4 and 5. Is there an easy way to do that without getting too complicated into threads etc?  
minifunc2();


minifunc3();
minifunc4();
minifunc5();
return "finished";
}

0
gagaliya
Asked:
gagaliya
  • 5
  • 4
  • 4
  • +3
2 Solutions
 
cjjcliffordCommented:
there is no direct way to return a value in the middle of processing a method.

However, you could pass in a callback object, and use that to pass out information midway:

public class MidwayCallback {
    public void callback( String arg ) {
        // do some processing here
        System.out.println( "Midway!" );
    }
}

public String somefunc( MidwayCallback callback ) {
    minifunc1();
    minifunc2();
    callback.callback( "midway!" );
    minifunc3();
    minifunc4();
    return "finished";
}

however, this will all work in the one thread of execution - to get the code in the callback to operate in parallel with the remainder of the function, you'll have to kick off a seperate thread (simple way is to change the Callback Class, e.g.

public class MidwayCallback {
    public void callback( String arg ) {
        // do some processing in a thread here
        new Thread( new Runnable() {
            public void run() {
                  System.out.println( "Midway: " + arg );
            }
         } );
    }
}
0
 
Venci75Commented:
public String somefunc
{
minifunc();

Thread t = new Thread(new Runnable() {
  public void run() {
    minifunc2();
  }
});


minifunc3();
minifunc4();
minifunc5();

t.join(0);
return "finished";
}
0
 
TrekkyLeaperCommented:
Make a Runnable class to execute your async functions:

public class ExecFuncs implements Runnable {
  int func;

  public ExecFuncs( int i ) {
    func = i;
  }

  public void run() {
    if( i == 3 ) {
      minifunc3();
    } else if( i == 4 ) {
       ....             // do 4 and 5 the same way
    }
  }
}


Modify your original call:

public String somefunc
{
minifunc();

minifunc2();


(new Thread( new ExecFuncs( 3 ) ) ).start();
(new Thread( new ExecFuncs( 4 ) ) ).start();
(new Thread( new ExecFuncs( 5 ) ) ).start();
return "finished";
}

Is that simple enough?
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
sudhakar_koundinyaCommented:
public String somefunc
{
minifunc();

minifunc2();
MyThread t=new MyThread();
t.start();

return "finished";
}

class MyThread extends Thread
{
   MyObject o;
    public MyThread(MyObject o)
    {
             this.o=0;
     }
    public void run()
     {

o.minifunc3();
o.minifunc4();
o.minifunc5();
     }
}
0
 
sudhakar_koundinyaCommented:
hahahaha  all at a time. You are stealing my points ;-)

No Worries. Just Kidding ;-)
0
 
sudhakar_koundinyaCommented:
forgot to mention

MyObject  is your main class that holds all your functions
0
 
Venci75Commented:
I didn't read you question carefully :(( so - disregard my comment
0
 
sudhakar_koundinyaCommented:
In my model. Just a small change

>>MyThread t=new MyThread();

MyThread t=new MyThread(this);
0
 
gagaliyaAuthor Commented:
hey guys thanks for all the help. I tested the implementation below and it works fine. But i am still worried it will mess up somehow in production, can you guys please take a look at the code below and let me know if this is the corrected way to do this? How about if i call function(String Id) many times in a for loop with different input Id. will that mess up anything? thanks!

public class SomeJavaBean implements java.io.Serializable
{
    String function(String Id)
    {
        MyThread t=new MyThread(Id);
        t.start();
        return "hello world";
    }

    class MyThread extends Thread
    {
         String MyId = null;
         public MyThread(String Id) {  MyId = Id;  }
         public void run()  {  functiontwo(MyId);    }
      }
}
0
 
doronbCommented:
Actually, you could use SwingUtilities.invokeLater(...);
0
 
doronbCommented:
Ummm... wait a sec, before even trying SwingUtilities... are you writing an application or is it a JSP/Applet?
0
 
sudhakar_koundinyaCommented:
Try this model. But I think it will a bit slow.

Hmmmmm..., First try it and let me know. I will help you furtherif you face any problems

public class SomeJavaBean implements java.io.Serializable
{
    String function(String Id)
    {
             synchronized(this)
          {
        MyThread t=new MyThread(Id);
        t.start();
        return "hello world";
         }
    }

    class MyThread extends Thread
    {
         String MyId = null;
         public MyThread(String Id) {  MyId = Id;  }
         public void run()  {  synchronized(this){functiontwo(MyId);  }  }
      }
}
0
 
cjjcliffordCommented:
gagaliya, you didn't post what functiontwo() does, so we can't really say what effects this would have.
Your initial request was to "return" a string in the middle of processing, before continuing on, I assumed you wanted to somehow return progress information, or something along this line - if you just want to have something process in the background, then you would be better to implement "functiontwo()" as a member function of the MyThread class (or even putting the logic into the run() method), keep all the code together and keep clean boundaries between classes (loose coupling, high cohesion). Then whenever you want the functionality run, just create a new MyThread class and start it!

sudhakar - Synchronizing the way you have won't do anything really - the code in SomeJavaBean.function() only deals with method-local variables, so synchronization will only result in queuing up requests to this function. Synchronization in MyThread.run() does nothing, since each call to SomeJavaBean.function() will create a new MyThread object, which is what is being synchronized in your code (i.e. each synchronization block has a different object to synchronize on: no synchronization...)
0
 
gagaliyaAuthor Commented:
cjjclifford, so you are saying the code below is better?  This is a jsp->javabean->db app and the threading is not used for progress. Mainly the performance is too slow, and we just want to return back to the user(jsp) midway. They dont need to wait until the whole thing finishes.

this is a more accurate version of my code. functiontwo establishes connection to the database, runs a perl script using system(), and calls a bunch other functions.

public class SomeJavaBean implements java.io.Serializable
{
    String function(String Id)
    {
        functionone();
        ............
        MyThread t=new MyThread(Id);
        t.start();
        return "hello world";
    }

    class MyThread extends Thread
    {
         String MyId = null;
         public MyThread(String Id) {  MyId = Id;  }
         public void run()  {  functiontwo(MyId);    }
         public void functiontwo(String id){.....functionthree();functionfour();....}
         public void functionthree(String id){}
         public void functionfour(String id){}

    }
}
0
 
cjjcliffordCommented:
something along these lines, yes.
When you say "JavaBean" are you referring to EJB? If you are using a J2EE Container/application server, you should use JMS - the JSP connect to the EJB, which does some work, sends a JMS message to get the remainder of the work done, and then EJB returns to JSP (which in turn returns to user). Then you'd simply have to write a Message-Driven-Bean (MDB) to consume the JMS messages, the MDB would be responsible for all the business logic, and all the threading/scheduling/resource management handled by the application server.

If not EJB, then you should consider using Thread pooling/queuing, to ensure you don't kill the system (thread creation is a little resource intensive, and if you have many many requests all creating threads,  your system will get swamped...)

When you say "perl script run with system()"  do you mean java.lang.Runtime.exec() ? (there is no system() call in Java....) That sounds like the long way around a problem (JSP -> Java -> OS -> Perl -> database) why not rewrite the perl in Java (JSP->Java->Database)
 
0
 
gagaliyaAuthor Commented:
cool thanks. this is not ejb, just regular javabean that is called within jsp.  And yes on the perl script, it is runtime.exec() sorry. The script actually calls the mail progie on linux and sends out emails, it doesnt do anything with db. basically my function 1)does some work with db 2)calls a bunch other functions(that connect to db and massages data) 3)calls the per script to send out an email 4)does more work with db.

We use weblogic connection pools. i dont think i need to worry about sync problems right, and will calling the main function ten times(limit) in a for loop like every min be enough to cause resource issues you mentioned? thanks again
0
 
cjjcliffordCommented:
large numbers of running threads (hundreds) can cause problems occassionally... if you are using weblogic, you should be able to make use of JMS and a simple message driven bean simply enough... that or a simple ThreadPool might be worth your while (I'm sure there's some good ones to download for free, have a look at Apache commons...)
0
 
gagaliyaAuthor Commented:
thanks all
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 5
  • 4
  • 4
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now