Как вы проверяете, какой поток выполняет код в Java?

У меня многопоточная Java-программа с кучей правил для потоковой обработки: например, код в классе A должен вызываться только из потока пользовательского интерфейса; 3 метода в классе B должны быть вызваны только из сетевого потока и т.д.

Любые предложения о том, как делать утверждения или другие проверки кода, которые соблюдают эти правила? Я бы хотел сделать эквивалент тестирования для "инвариантов", чтобы предотвратить ошибки кодирования при использовании потоков.

Ответы

Ответ 1

В дополнение к отличному предложению adamfisk существует также удобный метод для конкретного тестирования, является ли текущий поток потоком EDT:

EventQueue.isDispatchThread()

Ответ 2

Thread.currentThread(). GetName()

Ответ 3

Вы можете попробовать

assert Thread.currentThread() == expectedThread;

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

Thread.t = Thread.currentThread();
String name = t.getName();
t.setName("UI thread");
callUIThreadOnlyMethod();
t.setName(name);

Ответ 4

Рассмотрите вопрос об обращении. Рассмотрите вопрос о предотвращении, а не о принудительном исполнении.

Если класс Mangalor можно запускать только в потоке пользовательского интерфейса, ограничьте видимость класса Mangalor классами UI. Если методы talk() и listen() класса CanOnString должны выполняться только в сетевом потоке, ограничьте видимость этих методов классами, которые вы запускаете в своем сетевом потоке.

Ответ 5

Я бы сделал это в своем коде в классе A:

if(!"UI thread".equals(Thread.currentThread().getName())){
    throw new IllegalStateException("wrong thread running this class, thread name:"+Thread.currentThread().getName());
}

Ответ 6

Вы также можете проверить имя потока, используя журнал, например. log4j или logback, просто установите шаблон, включающий %thread следующим образом:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="INFO">
     <appender-ref ref="STDOUT" />
  </root>
</configuration>