1

I am trying to write a Utility class that helps to execute a task on a Separate Thread, providing the ability to do something before the task starts, and something after the task ends.

Something similar to android's AsyncTask

Here is such a class.

class MySync
{
    public void preExecute() {}

    public void executeInBackground() {}

    public void postExecute() {}

    public final void execute()
    {
        threadExecute.start();
    }

    private final Thread threadExecute = new Thread()
    {
            @Override
            public void run()
            {
                try
                {
                    MySync.this.preExecute();
                    MySync.this.executeInBackground();
                    MySync.this.postExecute();

                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }
            }
    };
}

Here is how this class is supposed to be used. Consumer of the class will override the methods as per the requirement.

class RegisterStudent extends MySync
{  
    @Override
    public void preExecute()
    {
        System.out.println("Validating Student details. Please wait...");
        try
        {
            Thread.sleep(2000);
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

    @Override
    public void executeInBackground()
    {
        System.out.println("Storing student details into Database on Server. Please wait...");
        try
        {
            Thread.sleep(4000);
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

    @Override
    public void postExecute()
    {
        System.out.println("Student details saved Successfully.");
    }
}

And finally starting the task:

public class AsyncDemo
{
    public static void main(String... args)
    {
        new RegisterStudent().execute();
    }
}

It seems to work fine. My question is, is this the correct way of achieving the Objective as mentioned in the Title? Any suggestions on how best this can be implemented?

Srinivas Cheruku
  • 1,314
  • 3
  • 11
  • 19
  • Possible duplicate of [How does one implement a truly asynchronous java thread](http://stackoverflow.com/questions/2676687/how-does-one-implement-a-truly-asynchronous-java-thread) – Lajos Arpad Apr 17 '16 at 12:43
  • I feel like this belongs on [Code Review](http://codereview.stackexchange.com/) – Jorn Vernee Apr 17 '16 at 12:44

3 Answers3

1

What's bad about this is that you're forcing users to extend your class. In java you can only extend 1 class. So a framework should not take that away.

Rather use an interface:

public interface AsyncTask {
    public default void preExecute() {}

    public default void executeInBackground() {}

    public default void postExecute() {}
}

And have users pass that to your utility class:

class MySync
{
    private AsyncTask task;

    public MySync(AsyncTask task) {
        this.task = task;
    }

    public final void execute()
    {
        threadExecute.start();
    }

    private final Thread threadExecute = new Thread()
    {
            @Override
            public void run()
            {
                try
                {
                    MySync.this.task.preExecute();
                    MySync.this.task.executeInBackground();
                    MySync.this.task.postExecute();

                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }
            }
    };
}
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
1

What I don't like with your approach is the fact that you create a new thread each time you create a new instance of MySync which is not scalable if you intend to create a lot of instances of your Object moreover it is costly to create a Thread, if I were you I would use an executor in order to limit the total amount of threads allocated to execute your tasks asynchronously, here is how you can do it if you want to use only one thread:

ExecutorService executor = Executors.newFixedThreadPool(1);

I would also re-write your code for something like this:

 public abstract class MySync implements Runnable {
    @Override
    public final void run() {
        try {
            preExecute();
            executeInBackground();
        } finally {
            postExecute();
        }
    }
    protected abstract void preExecute();

    protected abstract void executeInBackground();

    protected abstract void postExecute();
}

This way you define the whole logic for all the implementations.

Then you can submit your task like this:

executor.submit(new RegisterStudent());
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • Could you please explain how will this limit the number of Threads to be created? And why is postExecute() in finally block? – Srinivas Cheruku Apr 17 '16 at 14:59
  • 1. Executors.newFixedThreadPool(1) creates a thread pool with a fixed size of 1 thread max in the pool. 2. Just to make sure that postExecute is always executed but it is not required. For example you get a connection in preExecute and you commit and close in postExecute, in this case using try/finally block is needed – Nicolas Filotto Apr 17 '16 at 15:11
0

Loader is exactly what you are looking for. Here is introduction for loader

https://developer.android.com/guide/components/loaders.html
https://developer.android.com/reference/android/content/Loader.html

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Aditya
  • 371
  • 3
  • 8
  • How about doing this on a non-android Java platform? – Srinivas Cheruku Apr 17 '16 at 13:00
  • Can you describe what you exactly want to achieve. Like run an async call and wait for response and do animation or other stuff in that time or something else. – Aditya Apr 17 '16 at 14:52
  • I am trying to achieve something similar to what Asyntask provides us. But i think AsyncTask is limited to Android, so I was trying my own stuff. – Srinivas Cheruku Apr 17 '16 at 15:06