Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Event. Spring framework / 9 сообщений из 9, страница 1 из 1
11.01.2015, 17:35
    #38851726
TepKuH
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
Коллеги,
Нужна ваша помощь. Так как не знаю как получше реализовать следующая задачу:
1) Есть контроллер который в свою очередь вызывает сервис.
2) Сервис в свою очередь выполняет какой то процесс и может делать это очень долго
3) Есть другой контроллер при вызове которого происходит останов процесса запущенного в п.2
В упрощенной форме эт выглядит так:
1) Пользователь на странице в веб-браузере нажимает кнопку start
2) Пользователь в какой то момент считает что хватит на сегодня выполнять процесс и нажимает кнопку stop опять же на странице в браузере

И думается что задачу нужно делать через event'ы, но так как я собственно event'ы не имел необходимости разрабатывать то не могу понять как задачу можно реализовать.

Некоторый код моих контроллеров и сервис, выглядит бредово ибо не работает :)

Вызывающий сервис, контроллер:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
@Controller
@ApiIgnore
public class Test {    
    @Autowired
    private JobService jobService;

    @RequestMapping(value = "/mytest.html", method= RequestMethod.GET)
    public void processUpload() throws Exception{
        jobService.makeJob();
    }
}


Останавливающий сервис, контроллер:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Controller
public class StopJob {   
    @Autowired
    private EventProducer eventProducer;

    @RequestMapping(value = "/stopJob.html", method= RequestMethod.GET)
    public void processUpload() throws Exception{
        eventProducer.stopWork("my-job");
    }
}



Сам сервис:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
@Service
public class JobService {
    @Autowired
    private EventProducer eventProducer;

    private static final Logger log = Logger.getLogger(JobService.class);

    public void makeJob(){
        EventListener listener = new EventListener(){
            public void stopJob(RelationshipEvent myEvent){
                log.info("stopJob() " + myEvent.getMessage());
            }
        };
        eventProducer.addMyListener(listener);

        while (true){
            try{
                Thread.sleep(5000);
            }catch (InterruptedException ex){}
            log.info("make job");
        }
    }
}



EventProducer он собственно располагается в контексте сервера-приложений, чтобы любой сервис\контроллер имел к нему доступ:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
public class EventProducer {
    private ArrayList<EventListener> listeners = new ArrayList<>();
    public void addMyListener(EventListener listener){
        listeners.add(listener);
    }

    public ArrayList<EventListener> getEventListeners(){
        return listeners;
    }

    public void removeEventListener(EventListener listener){
        listeners.remove(listener);
    }

    protected void fireStop(String message){
        RelationshipEvent ev = new RelationshipEvent(this, message);
        for(EventListener listener : listeners)
            listener.stopJob(ev);
    }

    public void stopWork(String workName){
        fireStop("stop work " + workName);
    }
}
...
Рейтинг: 0 / 0
12.01.2015, 09:32
    #38851919
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
TepKuH,
Без лишней сущности Event код работает?
...
Рейтинг: 0 / 0
12.01.2015, 09:40
    #38851926
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
Вам сначала с потоками надо подружиться.
Thread
Его методом interupt()
Знанием почему метод stop() deprecated и как правильно останавливать потоки.
Java Concurrency Utilities
Особенно
ExectorService/Executors
FutureTask
Потом можно ознакомиться с аннотацией Spring @Async, раз уже этот фреймверк используется.

И только потом можете почитать про события, ибо оно тут не совсем к месту.

На самом деле реализация сводится к простому.
Делем в JobService метод, который возвращает FutureTask и помечаем его @Async
Метод обязательно должен вызываться из другого класса (Например контроллера), чтобы проходить через Spring AOP.
Тогда этот метод будет запускать задачу в фоновом потоке и в контексте Spring - так что все инъекции должны быть доступны.
FutureTask можно кинуть в сессию. Хотя придется озаботиться о сериализации. Можно просто в Map сложить про Session Id.
При вызове stop - по session id достаётся ссылка на этот FutureTask и отменяется.
...
Рейтинг: 0 / 0
12.01.2015, 09:43
    #38851930
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
В мануале масса примеров
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html
С FutureTask я прогнал:
Код: java
1.
2.
3.
@Async
public Future<ResultType> makeJob(){
}
...
Рейтинг: 0 / 0
12.01.2015, 15:20
    #38852330
TepKuH
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
BlazkowiczВам сначала с потоками надо подружиться.
Thread
Его методом interupt()
Знанием почему метод stop() deprecated и как правильно останавливать потоки.

Да идея была в том что есть работающий поток (EJB-компонента), этот поток подписывается на событие. В какой то момент случается эт самое событие(приходит jms) и хелдлер внутри работающей EJB-компоненты выставляет флаг, EJB-компонента в свою очередь постоянно проверяет наличие выставленного флага и в случаи если флаг выставлен в true, просто прекращает работу.
Насчет Thread я ведь думал. Там ситуация в том ссылку на thread надо где то хранить (самое очевидно в контексте приложения) но штука в том что у меня в будущем это приложение станет распределенным и нужно будет эту ссылку как то синхронизировать со всеми серверами. Ибо не известно где запущена эта EJB компонента реализующая бизнес-логику. А команда о прекращении может поступить на VIEW сервера где не запущена EJB компонента.

BlazkowiczJava Concurrency Utilities
Особенно
ExectorService/Executors
FutureTask
Потом можно ознакомиться с аннотацией Spring @Async, раз уже этот фреймверк используется.

И только потом можете почитать про события, ибо оно тут не совсем к месту.

На самом деле реализация сводится к простому.
Делем в JobService метод, который возвращает FutureTask и помечаем его @Async
Метод обязательно должен вызываться из другого класса (Например контроллера), чтобы проходить через Spring AOP.
Тогда этот метод будет запускать задачу в фоновом потоке и в контексте Spring - так что все инъекции должны быть доступны.
FutureTask можно кинуть в сессию. Хотя придется озаботиться о сериализации. Можно просто в Map сложить про Session Id.
При вызове stop - по session id достаётся ссылка на этот FutureTask и отменяется.
Ваше предложение оно конечно проверено временем, но вот ссылка на Thred... вот что не очень хорошо. Её хранить надо, в случаи же распределенных систем в итоге выйти может зоопарк.
А вообще как всегда вам спасибо. Вы постоянно чего то умное мне подсказываете. Я банально тоже хотел нечто подобное сделать, но чутка другими огородами. Ваше предложение более элегантно.
...
Рейтинг: 0 / 0
12.01.2015, 16:07
    #38852382
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
TepKuHДа идея была в том что есть работающий поток (EJB-компонента), этот поток подписывается на событие. В какой то момент случается эт самое событие(приходит jms) и хелдлер внутри работающей EJB-компоненты выставляет флаг, EJB-компонента в свою очередь постоянно проверяет наличие выставленного флага и в случаи если флаг выставлен в true, просто прекращает работу.
Насчет Thread я ведь думал. Там ситуация в том ссылку на thread надо где то хранить (самое очевидно в контексте приложения) но штука в том что у меня в будущем это приложение станет распределенным и нужно будет эту ссылку как то синхронизировать со всеми серверами. Ибо не известно где запущена эта EJB компонента реализующая бизнес-логику. А команда о прекращении может поступить на VIEW сервера где не запущена EJB компонента.

Ну, так код же выше приведет для Spring. Если надо EJB, то, конечно, Message-Driven Bean в зубы и можно тоже самое ваять.
На счет флага мысли верные. Надо только убедится что нет длинных транзкций.

TepKuHВаше предложение оно конечно проверено временем, но вот ссылка на Thred... вот что не очень хорошо. Её хранить надо, в случаи же распределенных систем в итоге выйти может зоопарк.
А вообще как всегда вам спасибо. Вы постоянно чего то умное мне подсказываете. Я банально тоже хотел нечто подобное сделать, но чутка другими огородами. Ваше предложение более элегантно.
Не надо нигде ссылку на Thread хранить. Потоками управляет либо JEE контейнер, либо Spring. Future это не Thread - это ссылка на результат, которого ещё нет, но когда он появится его можно через эту ссылку получить.
...
Рейтинг: 0 / 0
13.01.2015, 23:15
    #38853670
TepKuH
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
BlazkowiczНе надо нигде ссылку на Thread хранить. Потоками управляет либо JEE контейнер, либо Spring. Future это не Thread - это ссылка на результат, которого ещё нет, но когда он появится его можно через эту ссылку получить.
Поразмыслил я чутка и покурил чутка про Future<ResultType> я не понял как можно остановить работающий поток нигде не храня при этом ссылку на него. Эт у меня прямо таки ломает мой мозг. У Future есть кучи всяких методов типа Future.cancel(boolean) ну или Future.isDone() но метод нельзя выполнить без ссылки на объект Future. Значит надо его где то хранить и не важно ссылку на что хранить на Thread или на Future. А в случаи распределенной системы надо еще как то сихронизировать эти ссылки.

BlazkowiczНу, так код же выше приведет для Spring. Если надо EJB, то, конечно, Message-Driven Bean в зубы и можно тоже самое ваять.
На счет флага мысли верные. Надо только убедится что нет длинных транзкций.

Эхх, легко сказать возьмите MDB и с песнями. Не получается подписать на события именно тот Bean который начал выполняется :)
MDB он ведь по сути обычный Bean с одной оговоркой, он является слушателем слушателем JMS-сообщений, но можно подписать по сути на любые события. Для упрощения я сделаю не классический MDB, а bean который подписал на события ApplicationEvent.

Собственно два контроллера, один запускает процесс, другой останавливает.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@Controller
public class StartJob {
    @Autowired
    private JobService jobService;

    @RequestMapping(value = "/startJob.html", method= RequestMethod.GET)
    public void processUpload() throws Exception{
        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal().equals("anonymousUser")){
            throw new AccessDeniedException("anonymous is not allow");
        }

        CustomUserDetails customUserDetail = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Future<String> task = jobService.doJob(customUserDetail.getUsername());
        jobService.setThread(task);
        String result = task.get();
    }
}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
@Controller
public class StopJob {
    @Autowired
    private CustomEventPublisher customEventPublisher;

    @RequestMapping(value = "/stopJob.html", method= RequestMethod.GET)
    public void processUpload() throws Exception{
        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal().equals("anonymousUser")){
            throw new AccessDeniedException("anonymous is not allow");
        }
        CustomUserDetails customUserDetail = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        customEventPublisher.publishStopJob(customUserDetail.getUsername());
    }
}



Далее сам Bean реализующий саму логику

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
@Component
public class JobService implements ApplicationListener<StopJobEvent> {
    private static final Logger log = Logger.getLogger(JobService.class);
    private final ExecutorService pool = Executors.newFixedThreadPool(10);

    private String username;
    private Future<String> thread;

    public void onApplicationEvent(StopJobEvent event) {
        log.info("job need stop for user: " + event.getUsername());
        if (event.getUsername()==username){
            thread.cancel(true);
        }
    }

    @Async
    public Future<String> doJob(String username) {
        //Запоминаем от чего имени был запущен Bean
        this.username = username;

        return pool.submit(new Callable<String>() {
            public String call() throws Exception {
                for(int i=0;i<100;i++){
                    Thread.sleep(1000);
                    log.info(i + ": some job doing");
                }
                return "job is done";
            }
        });
    }

    public void setThread(Future<String> thread){
        this.thread = thread;
    }
}



Ну и для полноты картины сам event.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
public class StopJobEvent extends ApplicationEvent {
    private String username;

    public StopJobEvent(String username, Object source) {
        super(source);
        this.username = username;
    }

    public String getUsername(){
        return this.username;
    }
}



И вот собственно проблема получается в том чтобы именно работающие в данный момент в фоне процессы получали StopJobEvent
...
Рейтинг: 0 / 0
14.01.2015, 09:18
    #38853792
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
TepKuH Поразмыслил я чутка и покурил чутка про Future<ResultType> я не понял как можно остановить работающий поток нигде не храня при этом ссылку на него.
Потоки не нужно останавливать. Я выше перечислил материал для изучения. Это те основы, которые помогут понять что и как. Ломиться же использовать API, не понимая как он работает, действительно не лучший путь.

TepKuH
Эт у меня прямо таки ломает мой мозг. У Future есть кучи всяких методов типа Future.cancel(boolean) ну или Future.isDone() но метод нельзя выполнить без ссылки на объект Future. Значит надо его где то хранить и не важно ссылку на что хранить на Thread или на Future.

Ссылку на Thread хранит контейнер - Spring, JEE Server или ExecutorService.
Реализацию Future тоже предоставляет контейнер.
Ты вызываешь cancel() - реализация контейнера, если interrupt запрещен, просто удаляет задачу из очереди. Работающую задачу не прервать.
Если interrupt разрешен - то контейнер имеет ссылку на Thread и вызывает interrupt(). Реализация твоего Callable/Runnable должна уметь прерываться по interrupt(). Либо на блокировках, либо проверяя статус текущего потока.

TepKuH
А в случаи распределенной системы надо еще как то сихронизировать эти ссылки.

Это отдельная тема - не надо её сюда приплетать.

TepKuH
Эхх, легко сказать возьмите MDB и с песнями. Не получается подписать на события именно тот Bean который начал выполняется :)
MDB он ведь по сути обычный Bean с одной оговоркой, он является слушателем слушателем JMS-сообщений, но можно подписать по сути на любые события. Для упрощения я сделаю не классический MDB, а bean который подписал на события ApplicationEvent.

Продолжай игнорировать то что я пишу. И я тогда буду игнорировать вопросы. Сначала определись на чем делать на EJB или на Spring. В этой задаче их миксовать не нужно.

TepKuH
Собственно два контроллера, один запускает процесс, другой останавливает.
Код: java
1.
        String result = task.get();



А ещё я настоятельно рекомендую читать JavaDoc по каждому новому для тебя методу. Future.get() блокирует текущий поток и ждет окончания выполнения задачи в другом потоке. Это не совсем то что тебе нужно. Я же сказал. Future надо складывать в Map по Session Id. И отпускать поток - чтобы вернуть результат зарпоса в клиента (браузер).

TepKuH
Далее сам Bean реализующий саму логику
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
    //Почему не Spring @Async ??
    private final ExecutorService pool = Executors.newFixedThreadPool(10);
    // Future это не Thread. Это контейнер в котором в будущем будет ссылка на результат выполнения задачи.
    private Future<String> thread;

        //Запоминаем от чего имени был запущен Bean
        // Может Session ID?
        this.username = username;




TepKuH
И вот собственно проблема получается в том чтобы именно работающие в данный момент в фоне процессы получали StopJobEvent
Пример через сессию:
http://blog.inflinx.com/2012/09/09/spring-async-and-future-report-generation-example/

Важное замечание о том что Future не Serializable и так делать не хорошо.
http://blog.inflinx.com/2012/09/09/spring-async-and-future-report-generation-example/#comment-73353
...
Рейтинг: 0 / 0
14.01.2015, 15:57
    #38854385
TepKuH
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Event. Spring framework
BlazkowiczПотоки не нужно останавливать. Я выше перечислил материал для изучения. Это те основы, которые помогут понять что и как. Ломиться же использовать API, не понимая как он работает, действительно не лучший путь.

Читал я давно и вспоминал пару дней назад ходя по ссылкам. Я конечно допускаю что я что то упустил. Полагаю что вы хотите мне сказать что потоки нельзя останавливать эт типа не безопасно. Thread.stop() вообще объявлен Deprecated эт я знаю и так. Я в реальности то вообще поток не хочу останавливать, я хочу флаг выставить, а проверять флаг, но эт не суть важно, какой будет флаг какой нить внутри сервиса boolean isStopped или Future.isCancelled() или Thread.isInterrupted()

BlazkowiczСсылку на Thread хранит контейнер - Spring, JEE Server или ExecutorService.
Реализацию Future тоже предоставляет контейнер.
Ты вызываешь cancel() - реализация контейнера, если interrupt запрещен, просто удаляет задачу из очереди. Работающую задачу не прервать.
Если interrupt разрешен - то контейнер имеет ссылку на Thread и вызывает interrupt(). Реализация твоего Callable/Runnable должна уметь прерываться по interrupt(). Либо на блокировках, либо проверяя статус текущего потока.

Я понял механику Future точно так же. Даже чуть ниже привожу пример где реализовано на Future + проверка текущего статуса Future.isCancelled() внутри сервиса

BlazkowiczTepKuH
А в случаи распределенной системы надо еще как то синхронизировать эти ссылки.

Это отдельная тема - не надо её сюда приплетать.

Вот тут бы я поспорил, и сказал бы что эт основная проблема, ссылку на Thread или как вам угодно Future я могу легко кинуть в контейнер эт все очень просто. И пытаться сделать уже Thread.interrupt() или Future.cancel(true). А потом уже в моём работающем методе делать проверку на Thread.isInterrupted().
Сложность в том что у меня в будущем будет несколько серверов приложений. И в этом основная сложность, прошу прощенье что это в начале топика не обозначил

BlazkowiczПродолжай игнорировать то что я пишу. И я тогда буду игнорировать вопросы. Сначала определись на чем делать на EJB или на Spring. В этой задаче их миксовать не нужно.

Да где же я вас игнорирую то? Я внимательно слушаю, хожу по ссылкам что даёте. Возможно что то упускаю из виду, уж простите меня. Spring использую, с EJB - я прогнал. Думал просто на тот момент про переделку части кода на EJB, и тогда казалось эт здравой мыслью, сейчас уже не кажется.

BlazkowiczА ещё я настоятельно рекомендую читать JavaDoc по каждому новому для тебя методу. Future.get() блокирует текущий поток и ждет окончания выполнения задачи в другом потоке. Это не совсем то что тебе нужно. Я же сказал. Future надо складывать в Map по Session Id. И отпускать поток - чтобы вернуть результат запроса в клиента (браузер).

Окей, окей, про get() я не читал согласен виноват, потому что у меня работающий метод вообще не возвращает результатов. Не заострял я внимание на том что мне не нужно, взял первый попавший метод. У меня работающий метод читает из cassandra данные, производит с ними математику в циклах (своего рода реализация SQL JOIN'ов) и заполняет кэш ehcache. Дальше из другого потока происходит вычитка данных из кэша.
Но в какой то момент времени пользователь может внести изменения в персистентные данные хранящиеся в cassandra (уже в третьем потоке) и в этом случаи производить JOIN'ы не имеет уже смысл - данные то изменились. И должна случится очистка кэша ehcache и начаться история его заполнения снова. Вот тут и нужно рассылать события о прекращении расчетов всем контейнерам которые занимаются расчетами.
Т.е. в одном потоке, пользователь говорит, "а сделай ка мне SQL JOIN из noSQL БД :)" - начинается расчет
Из другого потока происходит вычитка данных и передача их посредством WebSocket клиенту
А из третьего контроллера пользователь решил внести изменения в данные. И вот тут как раз появляется проблема которую пытаюсь решить, эт остановить всех кто ведет расчеты по какой то конкретной ID-таблицы.
TepKuH
Далее сам Bean реализующий саму логику
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
    //Почему не Spring @Async ??
    private final ExecutorService pool = Executors.newFixedThreadPool(10);
    // Future это не Thread. Это контейнер в котором в будущем будет ссылка на результат выполнения задачи.
    private Future<String> thread;

        //Запоминаем от чего имени был запущен Bean
        // Может Session ID?
        this.username = username;



Да потому что не случается inject'а с этой аннотацией :) Spring не стартует, а я не стал разбираться почему, сделал как побыстрее лишь бы псевдо код этот нарисовать. Да и не нужны мне вообще результаты которые произведет Future. Мне Future по сути нужен чтобы ему сказать cancel(true) т.е. прибить по возможности.

TepKuH
И вот собственно проблема получается в том чтобы именно работающие в данный момент в фоне процессы получали StopJobEvent


Далее сам код слушающий события (близок к тому что я показал в топике, но с асинхронной реализацией на Future), пока в рамках одного контейнера, но не сложно переделываемый на прослушивающий JMS-сообщения. Код вроде работает за исключением момента когда нужно удалять листнер из хендлера. Мы храним ссылку на JobService, а случись с ним какая то бяда с ним - повис\кинул Exception ссылка не умрёт так и будет вечно хранится в хендлере.

Контроллеры:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
@Controller
public class StartJob {
    @Autowired
    private JobService jobService;

    @RequestMapping(value = "/startJob/{uuid}.html", method= RequestMethod.GET)
    public void createTable(@PathVariable UUID uuid){
        Future<String> future = jobService.doJob(uuid);
        jobService.setFuture(future);
    }
}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
@Controller
public class StopJob {    
    @Autowired
    private StopJobHandler stopJobHandler;

    @RequestMapping(value = "/stopJob/{uuid}.html", method= RequestMethod.GET)
    public void cleanTable(@PathVariable UUID uuid){

        StopJobEvent event = new StopJobEvent(uuid, this);
        stopJobHandler.stopJob(event);
    }
}



Сам сервис:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
@Component
public class JobService implements IStopJobListener {
    private static final Logger log = Logger.getLogger(JobService.class);

    private UUID uuidTable;
    private Future<String> thread;

    @Autowired
    private StopJobHandler stopJobHandler;

    public void onApplicationEvent(StopJobEvent event) {
        log.info("job need stop for user: " + event.getUuidTable());
        if (event.getUuidTable()==uuidTable){
            log.info("canceled for user: " + event.getUuidTable());
            thread.cancel(true);
            stopJobHandler.removeListener(this);
        }
        return;
    }

    public Future<String> doJob(UUID uuidTable) {
        stopJobHandler.addListener(this);
        this.uuidTable = uuidTable;

        try{
            for(int i=0;i<100;i++){
                Thread.sleep(1000);
                if (thread.isCancelled()){
                    break;
                }
                log.info(i + ": some job doing");
            }
        }catch (InterruptedException ex){

        }
        return new AsyncResult<>("job is done");
    }

    public void setFuture(Future<String> thread){
        this.thread = thread;
    }
}



Handler:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public class StopJobHandler {
    List<IStopJobListener> listeners = new ArrayList<>();
    public void addListener(IStopJobListener listener) {
        listeners.add(listener);
    }

    public List<IStopJobListener> getListener() {
        return listeners;
    }

    public void removeListener(IStopJobListener listener) {
        listeners.remove(listener);
    }

    public void stopJob(StopJobEvent event){
        for( int i = 0; i < listeners.size(); i++ ) {
            listeners.get(i).onApplicationEvent(event);
        }
    }
}



Ну и для полноты картины interface IStopJobListener
Код: java
1.
2.
3.
public interface IStopJobListener {
    public void onApplicationEvent(StopJobEvent event);
}
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Event. Spring framework / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]