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, 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 functionality. Note that this method cannot be used to test a class for multithreaded use.
Given a {{Thread}} object that has been constructed with a runnable argument, when invoking {{Thread.run()}}, the {{Thread}} object may be cast to {{Runnable}} to eliminate analyzer diagnostics.
{code:bgColor=#ccccff}
Thread thread = new Thread(new Runnable() {
public void run() {
// ...
}
});
((Runnable) thread).run(); // Exception: This does not start a new thread
{code}
Casting a thread to {{Runnable}} before calling {{run()}} documents that the explicit call to {{Thread.run()}} is intentional. Adding an explanatory comment 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 ||
| CON21- J | low | probable | medium | {color:green}{*}P4{*}{color} | {color:green}{*}L3{*}{color} |
h3. Automated Detection
TODO
h3. Related Vulnerabilities
Any vulnerabilities resulting from the violation of this rule are listed 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!|CON20TSM02-J. Do not use background threads during class initialization] [!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!|CON22-J. Always invoke wait() and await() methods inside a loop]
|