Thread Run Called Directly

ID

kotlin.thread_run_called_directly

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Kotlin

Tags

concurrency, reliability

Description

Reports calls to Thread.run(). Invoking run() directly executes the runnable in the caller’s thread; it does not spawn a new thread. The author of thread.run() almost always meant thread.start().

Rationale

val t = Thread { heavyComputation() }
t.run()        // FLAW — heavyComputation() runs on the current thread
t.start()      // OK — heavyComputation() runs on a new thread

Thread.run() exists because Thread implements Runnable. The contract of Runnable.run() says "do the work". Thread.start() is what actually spawns a new OS thread and arranges for run() to be invoked on it. Calling run() from your own code skips the spawning step entirely — the work still happens, but in the wrong thread, defeating the reason for creating a Thread in the first place.

Remediation

Call start() instead. If the surrounding code already accepts a runnable, prefer passing a lambda or Runnable directly to whatever scheduler is in use rather than allocating a Thread.

val t = Thread { heavyComputation() }
t.start()   // OK

// Or, even better, use a coroutine / executor
launch { heavyComputation() }

References