Как вы проверяете, какой поток выполняет код в Java? - PullRequest
14 голосов
/ 13 января 2011

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

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

Ответы [ 6 ]

16 голосов
/ 13 января 2011

Thread.currentThread (). GetName ()

13 голосов
/ 13 января 2011

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

EventQueue.isDispatchThread()
8 голосов
/ 13 января 2011

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

assert Thread.currentThread() == expectedThread;

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

Thread.t = Thread.currentThread();
String name = t.getName();
t.setName("UI thread");
callUIThreadOnlyMethod();
t.setName(name);
2 голосов
/ 13 января 2011

Попробуйте перевернуть вопрос.Рассмотрим предотвращение вместо применения.

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

1 голос
/ 13 января 2011

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

if(!"UI thread".equals(Thread.currentThread().getName())){
    throw new IllegalStateException("wrong thread running this class, thread name:"+Thread.currentThread().getName());
}
0 голосов
/ 29 января 2015

Вы также можете проверить имя потока, используя логирование, например, 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>
...