Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Контекст потока в Thread


Автор: Stampede 1.12.2005, 19:40
Ломая голову над одной интересной задачей, нашел совершенно потрясное решение. Решение и вправду красивое, но это такая крамола и ересь, что я решил сначала посоветоваться с вами на предмет возможных побочных явлений.

Значится, так. Есть поток. В нем происходят всякие интересные штуки. В частности, происходят обращения к компонентам, реализации которых наперед неизвестны. Компоненты эти, в свою очередь, тоже не знают, откуда их позвали. А хотелось бы владеть такой инфой.

Разумеется, передать такую инфу можно миллионом разных способов, но тут есть одно но: любое из этих решений привносит зависимости и/или утяжеляет API. А хотелось бы, чтобы API был чистым и незамутненным. Короче, классическая задача для AOP. И тут я подумал...

... А что если приделать какой-нибудь контекст к самому треду? Тогда в него можно было бы совать всякую полезную инфу и по ходу добавлять разные смешные подробности! tux, see where I'm getting at?

Ну и вот я давай смотреть, нет ли чего похожего в Thread. На первый взгляд как будто нет. Но вот на второй... Если внимательно приглядеться, есть такой метод, setName(String name), и соответствующий геттер. А что такое, товарищи, String name? Да ведь это же бездонное вместилище какой угодно инфы!

Я, конечно, тут же сел и попробовал:

Код
package com.acme.test;

public class TestThreadSetName
{
    public static void m1()
    {
        System.out.println("Before:\t" + Thread.currentThread().getName());
        m2();
        System.out.println("After:\t" + Thread.currentThread().getName());
    }

    public static void m2()
    {
        Thread t = Thread.currentThread();
        t.setName(t.getName() + ";ctx=12345");
    }

    public static void main(String[] args)
    {
        m1();
    }

}


Выводит:

Код
Before:    main
After:     main;ctx=12345


Работает! Вы представляете, какая моща открывается перед нами?

Но не все так просто, на самом деле. Совсем просто было бы неинтересно smile

Дело в том, что метод может выкидывать исключение, по счастью нечекнутое:

Цитата
Throws:
    SecurityException - if the current thread cannot modify this thread.


Поэтому хотелось бы поговорить на такую тему: от чего это зависит и что и при каких условиях можно гарантировать.

Прошу высказываться, товарищи smile

Автор: LSD 1.12.2005, 21:45
Не знаю огорчу тебя или порадую, но есть такая штука java.lang.ThreadLocal которая позволяет организовать контекст потока намного легче:
Код
public class Context
{
  private static ThreadLocal<HashMap> context = new ThreadLocal<HashMap>();
  
  public static HashMap getContext()
  {
    HashMap hashMap = context.get();
    if(hashMap == null)
    {
      hashMap = new HashMap();
      context.set(hashMap);
    }
    return hashMap;
  }
}

Автор: LSD 1.12.2005, 22:01
По поводу SecurityException, оно выбрасывается только если установлен SecurityManager. Для обычных приложений он как правило отсутствует, если только апплеты.

Автор: Stampede 1.12.2005, 22:27
Цитата(LSD @ 1.12.2005, 21:45)
Не знаю огорчу тебя или порадую


Да уж конечно порадовал. Я ж не хакер какой, чтобы любить делать вещи через задний проход smile

Спасибо, вот чего не знал, того не знал. Кстати, если об этой штуке заранее не знаешь, то самостоятельно обнаружить ее существование не так-то просто. Если задать поиск, например, по java thread context, то все ссылки будут или про своп (аппаратного) контекста потока, или про контекстный загрузчик класса.

Так что еще раз спасибо, и получите плюсом в репу smile

Автор: LSD 1.12.2005, 22:39
Цитата(Stampede @ 1.12.2005, 22:27)
Кстати, если об этой штуке заранее не знаешь, то самостоятельно обнаружить ее существование не так-то просто.

Я нашел эту штуку когда читал про многопоточное программирование, правда по моему это была не Sun-овская дока. А еще есть хорошие утилитки для многопоточного программирования java.util.concurrent. Сам пользуюсь, очень удобно, но это правда в 1.5.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)