简体   繁体   中英

Trying to write a class that allows to do something before the Thread starts and after the Thread finishes

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?

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();
                }
            }
    };
}

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM