2011-01-13 2 views
13

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

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

ответ

12

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

EventQueue.isDispatchThread() 
+1

+1 - при написании Swing вопрос UI/не-UI, как правило, является единственным, что важно. – kdgregory

+1

спасибо, я не использую качели, но, полагаю, многие люди будут читать это. – Nils

16

Thread.currentThread() GetName()

+0

+1 Care, чтобы закруглить свой ответ с ответом RD01 для свинга случае? – Nils

1

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

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

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

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

7

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

assert Thread.currentThread() == expectedThread; 

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

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

Существуют ли сценарии, кроме вредоносного кодера, где будет происходить подобное наложение? – Nils

+0

Плохие стандарты именования нитей и ошибки копирования. Большинство программ не написаны, чтобы гарантировать, что имена потоков уникальны, и вы часто видите повторяющиеся имена. –

0

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