Пусть у вас есть метод, вызываемый во многих местах, и вызов которого хочется сделать параллельным. Это можно сделать, не меняя код вызова метода и код самого метода. Нужно только создать расширение объемлющего класса, и изменить код создания объекта.
Было:
Стало:
Основная доработка состоит в переопределении распараллеливаемого метода:
SerialExecutor можно взять из документации на java.util.concurrent.Executor. Оптимизированный вариант — у меня в github.com/rfqu/CodeSamples. Он исполняет поданые ему задачи последовательно, тем самым избавляя от необходимости вводить синхронизацию в метод longJob(): все вызовы этого метода будут исполняться по очереди. Если в классе Service несколько публичных методов, их все надо переопределить тем же способом, и все они будут выполняться последовательно, из одной очереди.
Разумеется, этот способ применим не всегда и не решает всех проблем. Например, более крупные правки потребуются, если метод возвращает значение, или если один публичный метод вызывает другой публичный распаралелленый метод.
Идея с переопределением взята из Project Lombok.
Было:
class Service { public void longJob(Object arg) {...} } ... Service s=new Service(); ... s.longJob(arg);
Стало:
class Service { public void longJob(Object arg) {...} } class ServiceWrapper extends Service { ... } ... Service s=new ServiceWrapper() ; ... s.longJob(arg);
Основная доработка состоит в переопределении распараллеливаемого метода:
class ServiceWrapper extends Service { SerialExecutor executor=new SerialExecutor(trueExecutor); public void longJob(final Object arg) { executor.execute(new Runnable() { public void run() { ServiceWrapper.super.longJob(arg); } }); } }
SerialExecutor можно взять из документации на java.util.concurrent.Executor. Оптимизированный вариант — у меня в github.com/rfqu/CodeSamples. Он исполняет поданые ему задачи последовательно, тем самым избавляя от необходимости вводить синхронизацию в метод longJob(): все вызовы этого метода будут исполняться по очереди. Если в классе Service несколько публичных методов, их все надо переопределить тем же способом, и все они будут выполняться последовательно, из одной очереди.
Разумеется, этот способ применим не всегда и не решает всех проблем. Например, более крупные правки потребуются, если метод возвращает значение, или если один публичный метод вызывает другой публичный распаралелленый метод.
Идея с переопределением взята из Project Lombok.