The javadoc for the Thread
class shows two ways to define and use a thread:
Using a custom thread class:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeThread p = new PrimeThread(143);
p.start();
Using a Runnable
:
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
(Source: java.lang.Thread
javadoc.)
The custom thread class approach works, but it has a few problems:
It is awkward to use PrimeThread
in a context that uses a classic thread pool, an executor, or the ForkJoin framework. (It is not impossible, because PrimeThread
indirectly implements Runnable
, but using a custom Thread
class as a Runnable
is certainly clumsy, and may not be viable ... depending on other aspects of the class.)
There is more opportunity for mistakes in other methods. For example, if you declared a PrimeThread.start()
without delegating to Thread.start()
, you would end up with a "thread" that ran on the current thread.
The approach of putting the thread logic into a Runnable
avoids these problems. Indeed, if you use an anonymous class (Java 1.1 onwards) to implement the Runnable
the result is more succinct, and more readable than the examples above.
final long minPrime = ...
new Thread(new Runnable() {
public void run() {
// compute primes larger than minPrime
. . .
}
}.start();
With a lambda expression (Java 8 onwards), the above example would become even more elegant:
final long minPrime = ...
new Thread(() -> {
// compute primes larger than minPrime
. . .
}).start();