2014-09-25 3 views
-2

Я использую Quarts Scheduler для планирования работы. У меня есть разные задания, которые ежедневно получают медицинский отчет разных пользователей и отправляют этот отчет отдельному пользователю. У каждого задания есть определенный пользователь, связанный с ним. Прежде чем каждое задание начнет выполнять свою бизнес-логику, класс реализации JobListener создает экземпляр класса UserJobExecution.Проблема переключения контекста между двумя потоками

public class UserJobExecution 
{ 
    static ThreadLocal currentExecution = new ThreadLocal() 
    User user; 
    static UserJobExecution getCurrent(){ 
    (UserJobExecution) currentExecution.get(); 
    } 
    UserJobExecution(String jobName){ 
    try 
    { 
     user = getUserFromDB(jobName); 
    } 
    catch(e) 
    { 
     e.printStackTrace(); 
    } 
    } 
    User getUser(){ 
     return user; 
    } 
    //rest of the code 
} 

class WebServiceUtil{ 
    static HttpClient client = new HttpClient(new MultiThreadedHttpConnectionManager()); 
    User user; 
    WebServiceUtil(User user){ 
    this.user = user; 
    } 
    static WebServiceUtil getDefaultWs(){ 
    UserJobExecution userJobExecution = UserJobExecution.getCurrent(); 
    return (new WebServiceUtil(userJobExecution.getUser())); 
    } 
    static execute(String request){ 
    getDefaultWs().executeService(request); 
    } 

} 

Оба вышеуказанных класса имеют объект User, который имеет два имени пользователя и пароль. Каждое задание выполняет вызов общего веб-сервиса, вызывая его executeMethod с его собственным именем пользователя и паролем, чтобы получить медицинский отчет, связанный с конкретным пользователем. Веб-сервис требует времени для обработки отчета. Поэтому сначала задание запрашивает отчет и получает идентификатор отчета, а затем задание непрерывно вызывает веб-сервис для получения этого отчета каждые 15 секунд, пока веб-служба не обработает отчет, и задание не получит отчет.

Проблема я столкнулся в том, что если есть несколько заданий запускается в то же время, то он путает имя пользователя и пароль. (Метод, приведенный выше getCurrent() вызывается, чтобы получить настоящее время выполнения задания)

Я создаю один экземпляр UserJobExecution для каждой работы. Метод jobToBeExecuted вызывается Планировщиком для каждого задания до его выполнения.

public class ExecutionJobListener implements JobListener { 
    public void jobToBeExecuted(JobExecutionContext context){ 
    //Other code 
    UserJobExecution userJobExecution = new UserJobExecution(job) 
    userJobExecution.save() 
    } 
//Rest of the code 
} 

ответ

0

Вы, кажется, используете один экземпляр UserJobExecution для всех заданий, что приводит к классической проблеме синхронизации. Поскольку все задания используют один и тот же атрибут User в одном экземпляре UserJobExecution, несколько заданий могут одновременно вызвать getUserFromDB(), и пользовательский атрибут будет перезаписан.

Постарайтесь создать свой класс, чтобы все задания не сохраняли результат getUserFromDB(), используя ссылку, которая используется совместно между заданиями (например, используйте отдельные ссылки для каждого задания, например, сохраняя локальную переменную).

+0

Hi Personne3000 ... Я создаю один экземпляр UserJobExecution для каждой работы .. Я редактировал вопрос, добавленный код в конце. –

+0

Хорошо, не могли бы вы объяснить, как вы используете статический метод getDefaultWs() , а также метод getCurrent()? Они используют один и тот же экземпляр UserJobExecution каждый раз, поэтому я думал, что вы его используете. – personne3000

0

Непонятно из вашего вопроса, какой метод планируется использовать с помощью Quartz Scheduler. Тем не менее я предполагаю, что ошибка исходит от использования ThreadLocal в сочетании с планировщиком. Quartz Scheduler использует внутренний пул потоков для запуска заданий. Когда задание вызывается, вы не можете быть уверены, какой поток из пула он вызывается. Это может быть тот же поток или любой другой поток. Рассмотрите возможность использования JobDataMap для сохранения состояния задания.

Смежные вопросы