Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: reworded a bit based on draft-one edits; marking as needs-review
Wiki Markup
It is critical to ensure that threads are started correctly. Thread start-up can be misleading because sometimes the code appears to be performing the function correctly, when in fact it may be executing in the wrong thread. 

The {{Thread.start()}} method starts executing a thread's {{run()}} method in the respective thread. It is a mistake to directly invoke the {{run()}} method on a {{Thread}} object. When invoked directly, the statements in the {{run()}} method execute in the current thread instead of the newly created thread. Furthermore, if the {{Thread}} object is not constructed from a {{Runnable}} object but rather by instantiating a subclass of {{Thread}} that does not override the {{run()}} method, then a call to the subclass's {{run()}} method invokes {{Thread.run()}} which does nothing. {mc} can we rephrase "does nothing", for e.g. "method invokes {{Thread.run()}} which has an empty run() method"? {mc}


h2. Noncompliant Code Example

This noncompliant code example explicitly invokes {{run()}} in the context of the current thread. 

{code:bgColor=#FFCCCC}
public final class Foo implements Runnable {
  public void run() {
    // ...
  }
  
  public static void main(String[] args) {
    Foo foo = new Foo();
    new Thread(foo).run();
  }
}
{code}

The {{start()}} method is not invoked on the new thread because of the incorrect assumption that {{run()}} starts the new thread. Consequently, the statements in the {{run()}} method execute in the same thread instead of the new one.

h2. Compliant Solution

This compliant solution correctly uses the {{start()}} method to start a new thread. The {{start()}} method internally invokes the {{run()}} method in the new thread.

{code:bgColor=#ccccff}
public final class Foo implements Runnable {
  public void run() {
    // ...
  }
  
  public static void main(String[] args) {
    Foo foo = new Foo();
    new Thread(foo).start();
  }
}
{code}

h2. Exceptions

*EX1*: The {{run()}} method may be invoked when unit testing its functionality. Note that a class cannot be tested for multithreaded use by invoking {{run()}} directly.

{mc}{{Thread}} already implements {{Runnable}}{mc}
*EX2*: When using a invoking in the current thread, the {{Threadrun()}} objectmethod that has been constructed with of a distinct {{RunnableThread}} object, andthat whenhas needingbeen toconstructed executewith thea object's {{run()}} method in the current threadrunnable argument, the object should first be cast to a {{Runnable}} before invoking {{run()}}.

{code:bgColor=#ccccff}
Thread thread = new Thread(new Runnable() {
    public void run() {
      // ...
    }
  });
// Invoking thread.run() is bad; the programmer probably meant thread.start()
((Runnable) thread).run();  // (Admissible) Warning: This does not start a new thread 
{code}

Casting a thread to a {{Runnable}} before calling {{run()}} serves to document the intention of explicitly calling {{Thread.run()}}. Adding a disclaimer alongside the invocation is highly recommended.


h2. Risk Assessment

Failing to start threads correctly can cause unexpected behavior.

|| Rule || Severity || Likelihood || Remediation Cost || Priority || Level ||
| CON05- J | low | probable | medium | {color:green}{*}P4{*}{color} | {color:green}{*}L3{*}{color} |

h3. Automated Detection

TODO

h3. Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the [CERT website|https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+CON08-J].

h2. References

\[[API 06|AA. Java References#API 06]\] Interface {{Runnable}} and class {{Thread}}

----
[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_left.png!|CON04-J. Synchronize using an internal private final lock object]      [!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_up.png!|11. Concurrency (CON)]      [!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_right.png!|VOID CON06-J. Do not defer a thread that is holding a lock]