2012-04-16 2 views
1

В настоящее время я работаю над системой регистрации событий/действий, которую я реализую как аспект с использованием перехватчиков методов. На данный момент система/структура предполагает, что каждый метод является одним действием, но я хочу расширить его, чтобы активность могла охватывать несколько вызовов методов. Для этого первый подход, который приходит на ум, заключается в предоставлении некоторого контекста всем связанным вызовам методов. Тем не менее, я знаю только способ сделать это, если все вызовы методов находятся в контексте одного потока (например, MDC/NDC Log4J). Есть ли способ предоставить контекст для нескольких потоков (возможно, без кода, который знает многопоточность)?Java - создание контекста ведения журнала для нескольких потоков

ответ

1

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

+1

, это не так просто. Одна из потенциальных проблем такова: http://stackoverflow.com/questions/7296623/inheritablethreadlocal-and-thread-pools. Вот почему я всегда подчеркиваю, что такой контекст нужно настраивать явным образом. –

+0

Моя единственная проблема с вашим предложением прямо сейчас в том, что приложение, над которым я работаю, в настоящее время не имеет явного нереста потоков. Некоторые сторонние API могут делать это в фоновом режиме, но пока нет никого, что я знаю. Я вполне доволен любой ограниченной поддержкой многопоточного контекста, предлагаемой InheritableThreadLocal. Я обязательно буду учитывать ваши предложения, поэтому я могу использовать их, когда буду сталкиваться с такими проблемами в будущем. Благодарю. –

1

Класс ThreadLocal? Этот sems, как и на самом деле, может быть допустимым и удобным для использования TLS - добавление cotext к уже существующему коду.

+0

На самом деле это то, что я планирую использовать. Я просто не уверен, что он по-прежнему будет работать с многопоточным процессом. –

+0

ThreadLocal предназначен для решения определенной проблемы при многопоточности (и в моем ответе ContextManager обычно реализуется с помощью ThreadLocal внутри). Основная проблема, о которой вы должны подумать, - это способ переноса контекстного контента в другой поток. Помните, что есть много способов сделать ваше приложение многопоточным. Нерест новой темы каждый раз, как правило, самый худший способ сделать. То, как вы выполняете многопоточность, наверняка повлияет на способ распространения контекста. –

4

Не думайте о «регистрации». Это относится к чему-то еще более фундаментальному: если вы хотите, чтобы действия, выполняемые несколькими потоками, обрабатывались в одном контексте, что вы распространяете, чтобы каждый поток знал, в каком контексте они находятся?

Если вы можете ответить на этот вопрос, то этот контекст - это то, что вам нужно добавить в MDC/NDC для ведения журнала (возможно, не для всего контекста, а для этого есть ключевая информация в этом контексте).

Если ваше приложение не несет такую ​​информацию, никто не может определить, что для вас.


Edit:

Я могу дать и некоторое представление о том, как вы можете выполнить настройку. Является ли это целесообразно использовать АОП для дальнейшего повышения его, что ваше дальнейшее исследование :)

// Assume I have a ContextManager which Context is stored in thread local: 

abstract class ContextAwaredJob implements Runnable { 
    public ContextAwaredJob() { 
    this.context = ContextManager.getCurrentContext(); 
    } 
    public void run() { 
    ContextManager.setCurrentContext(this.context); 
    doRun(); 
    } 
    protected abstract void doRun(); 
} 

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

+0

+1, абсолютно. Этот контекст должен быть каким-то образом настроен. –

+0

Я не уверен, правильно ли я это понимаю. Во всяком случае, поскольку подход ориентирован на аспект, в фоновом режиме будет компонент, которому будет поручено отслеживать контекст, скажем, ContextManager. Я хотел бы структурировать его таким образом, чтобы независимо от способа выполнения любого метода, будь то в том же или другом потоке из исходного стека выполнения, контекст остается тем же. Я не уверен, что я имею здесь смысл; У меня нет большого опыта многопоточности (по крайней мере, не напрямую). –

+0

Проблема заключается «в том же или другом потоке из исходного стека исполнения». Как правило, стеки вызова метода в одном стеке можно разумно считать находящимися в одном контексте. Однако, когда у вас есть другой поток для выполнения, никто, кроме u, не знает правильный контекст. Например, у вас есть диспетчер заданий, который ставит задания для пула потоков для запуска.Вы хотите, чтобы «контекст» был сеансом пользователя, вам нужно настроить контекст для нового потока. Я считаю, что в этом случае конкретный специфический контекст fw setup, но только вы знаете, что вы действительно хотите –

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