CheckThread.org

Examples

Example 1: Hello World
  • In the snippet below, the constructor, HelloWorldThread(), and main() method both run on the main thread.
  • The methods run() and helloworld() both run on the helloWorldThread.
  • @ThreadConfined annotations are used to document the above threading model.
  • Running CheckThread on the example below will not produce any errors.
import org.checkthread.annotations.*;

public class HelloWorldThread extends Thread {

    @ThreadConfined(ThreadName.MAIN)
    public HelloWorldThread() {
        //runs on main thread 
        super();
        start();
    }

    @ThreadConfined("helloWorldThread")
    public void run() {
         // runs on hello world thread  
         helloworld();
    }

    @ThreadConfined("helloWorldThread")
    public void helloworld() {
        // runs on hello world thread 
        System.out.println("Hello World!");
    }
    
    @ThreadConfined(ThreadName.MAIN)
    public static void main(String[] args) {
        // runs on main thread 
        new HelloWorldThread();
    }
}

CheckThread Output: No errors

Example 2: Hello World With a Class Annotation

  • If a method does not have a @ThreadConfined, CheckThread will look for an annotation at the method's class definition.
  • This avoids "annotation clutter" in Java code.
  • Generally most Java classes will have a significant portion of their methods run on the same thread, so only a few annotations will be necessary.
  • From a thread policy standpoint, this example is equivalent to the previous example.

import org.checkthread.annotations.*;

@ThreadConfined(ThreadName.MAIN)
public class HelloWorldThreadClassAnnotation extends Thread {

    public HelloWorldThreadClassAnnotation() {
        // runs on main thread 
       super();
       start();
    }

    @ThreadConfined("helloWorldThread")
    public void run() {
        // runs on hello world thread  
        helloworld();
    }

    @ThreadConfined("helloWorldThread")
    public void helloworld() {
        // runs on hello world thread   
        System.out.println("Hello World!");
    }
    
    public static void main(String[] args) {
       // runs on main thread 
       new HelloWorldThread();
    }
}	  

CheckThread Output: No errors

Example 3: Hello World With a Bug

  • In the next example, the Java developer goofs and incorrectly calls helloworld() from the main thread.
  • As it is defined, helloworld() is only supposed to run on the "helloWorldThread", not the main thread.
  • In this example, the implementation of helloworld() is doing a simple print out, but in practice this method could be loading a driver or other resource that must be called on a specific thread.
  • Running CheckThread on this example will produce an error.

import org.checkthread.annotations.*;
@ThreadConfined(ThreadName.MAIN)
public class HelloWorldThreadWithBug extends Thread {

    public HelloWorldThreadWithBug() {
        // runs on main thread 
       super();
       start();
       helloworld(); // THREAD BUG HERE!!!
    }

    @ThreadConfined("helloWorldThread")
    public void run() {
        // runs on hello world thread  
        helloworld();
    }

    @ThreadConfined("helloWorldThread")
    public void helloworld() {
        // should run on hello world thread   
        System.out.println("Hello World!");
    }
    
    public static void main(String[] args) {
       // runs on main thread 
       new HelloWorldThread();
    }
}	  

CheckThread Output:
Thread policy mismatch error in HelloWorldThreadWithBug
calling helloworld

Example 4: Hello World Modified

  • In the next example, the Java developer decides that helloworld() can run safely on any thread. The Java developer makes this decision based on the implementation of the method.
  • The Java developer adds the @ThreadSafe annotation to the helloworld() method.
  • CheckThread will no longer throw an error.
import org.checkthread.annotations.*;
@ThreadConfined(ThreadName.MAIN)
public class HelloWorldThreadWithBugFixed extends Thread {

    public HelloWorldThreadWithBugFixed() {
       // runs on the main thread
       super();
       start();
       helloworld(); // OK
    }

    @ThreadConfined("helloWorldThread")
    public void run() {
        // runs on hello world thread
        helloworld(); // OK
    }

    @ThreadSafe
    public void helloworld() {
        // this method can run on any thread
        System.out.println("Hello World!");
    }
    
    public static void main(String[] args) {
       // runs on main thread
       new HelloWorldThread();
    }
}	  
	  

CheckThread Output: No errors

Example 5: Simple Swing Code

  • A common threading bug when working with Swing is to inadvertantly call a Swing method on the wrong thread (any thread other than the event-dispach thread).
  • This bug can lead to sporadic behavior (e.g. painting issues, gray windows, etc) that is difficult to track down.
  • The following example demonstrates how this bug can be caught at static analysis time by treating the Java code with the thread policy annotations.
  • ThreadName.EDT is a "pre-canned" string representing the Event-Dispatch Thread within @ThreadConfined annotations.
// some java class
import org.checkthread.annotations.*;

@ThreadConfined(ThreadName.MAIN)	
public void method1() {
    //THREADING BUG! Calling method2 from main thread
method2();
}

@ThreadConfined(ThreadName.EDT) public void method2() { // should only run on EDT thread
jButton.setBackground(...) }

Running CheckThread analyzer on this code would throw the following error:


Thread policy mismatch error calling method2 from method1
©2008 CheckThread