Пусть у вас есть метод, вызываемый во многих местах, и вызов которого хочется сделать параллельным. Это можно сделать, не меняя код вызова метода и код самого метода. Нужно только создать расширение объемлющего класса, и изменить код создания объекта.
Было:
Стало:
Основная доработка состоит в переопределении распараллеливаемого метода:
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.