I have a multi-threaded Java program with a bunch of rules around threading: For example, code in class A should only be called from the UI thread; 3 methods in class B must be called only from the network thread, etc.
Any suggestions on how to do assertions or other code checks that these rules are being followed? I'd like to do the equivalent of开发者_JS百科 testing for "invariants" to prevent coding errors on thread usage.
Thread.currentThread().getName()
In addition to adamfisk's excellent suggestion, there is also a convenience method for specifically testing whether the current thread is the EDT thread:
EventQueue.isDispatchThread()
You can try
assert Thread.currentThread() == expectedThread;
The problem with using the name is that any number of threads can use that name e.g. if you are particularly paranoid you might worry about code like this.
Thread.t = Thread.currentThread();
String name = t.getName();
t.setName("UI thread");
callUIThreadOnlyMethod();
t.setName(name);
Consider inverting the question. Consider prevention instead of enforcement.
If class Mangalor can only be run in a UI thread, limit the visibility of the Mangalor class to UI classes. If methods talk() and listen() of class CanOnString must only be run in a networking thread, limit the visibility of those methods to classes that you run in your networking thread.
I would do like this in my code in class A:
if(!"UI thread".equals(Thread.currentThread().getName())){
throw new IllegalStateException("wrong thread running this class, thread name:"+Thread.currentThread().getName());
}
You can also check thread name using logging e.g. log4j or logback, just set a pattern including %thread
like this:
<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>
精彩评论