Refactoring: Sync. to Async.

Suppose that we are given a class Foo that contains some expensive methods; they make some complex operations and these operations take much time.

Sometimes, that kind of methods might be too slow for being left single-threaded.

For instance, assume you have a GUI view and when user clicks a button in the interface, one of these methods are called.

If you had faced with this type of issues before, you would immediately tell that GUI window is going to freeze and remain nonfunctional until the method call is completed.

Let’s illustrate this scenario with an example.

(I am not going to include a GUI for that, this is left as practice. )

package ali.test;

public class Foo {

public Foo()
{
}

public void performFirstTask() throws InterruptedException
{
Thread.sleep(3000);
System.out.println(“Foo : the first complex task has been completed…”);
}

public void performSecondTask() throws InterruptedException
{
Thread.sleep(3000);
System.out.println(“Foo : the second complex task has been completed…”);
}

}
public static void main(String[] args) throws InterruptedException
{
System.out.println(“Foo obj. will complete a complex task.”);
Foo f = new Foo();
f.performFirstTask();
f.performSecondTask();
System.out.println(“end of sequence”);

}

The output would be

Foo obj. will complete a complex task.
Foo : the first complex task has been completed…
Foo : the second complex task has been completed…
end of sequence

If, as the developer, you are allowed to modify Foo, then no problem, you can simply add Threading support to it. If you were not allowed to do that, what would you do ?

The solution is amazingly simple with AOP.

package ali.test;

public aspect FooThreadingAspect {

pointcut FooThreadingOperations() : call(void Foo.*());

void around() : FooThreadingOperations()
{
Thread t = new Thread()
{
public void run()
{
proceed();
}
};

t.start();
}

}

That’s it, we’re done! Now, each method in class Foo is working asynchronously; making output

Foo obj. will complete a complex task.
end of sequence
Foo : the first complex task has been completed…
Foo : the second complex task has been completed…

However, be careful using this technique. Add an annotation to class Foo or its methods and clearly indicate that the methods are working asynchronously. If you are not allowed to do that, you can still use AOP to declare warnings.

If you skip these details, this technique has potential to become very dangerous.

Tags:

Leave a Reply