Threads
Threads are parts of a program that run on their own while the rest of the program does something else. This also is called multitasking because the program handles more than one task simultaneously.
Threads are ideal for anything that takes up a lot of processing time and runs continuously.
By putting a program’s hardest workload into a thread, you free up the rest of the program to handle other things. You also make the program easier for the JVM because the most intensive work is isolated.
Writing a Threaded Program
- Threads are implemented in Java with the
Threadclass in thejava.langpackage. - A thread can be created in two ways: by subclassing the
Threadclass or implementing theRunnable interfacein another class. BothThreadandRunnablebelong to thejava.langpackage.
-
Implement the
Runnable interfacein the class which will contain the thread (the "threaded object").public class MyThread implements Runnable {
public void run() { /*code which is run in the thread*/ }
}- The interface implements only the
run()method.
- The interface implements only the
-
Create a "thread object" by calling the "
Threadconstructor" with the "threaded object" as argument.Thread runner = new Thread(new MyThread()); -
The
startmethod will start the thread by calling therun()method. The thread is running independent from the rest of the program as long therun()method runs.runner.start()example: simple thread
public class SimpleThread {
public static void main(String[] args) {
Thread runner = new Thread(new MyThread("first"));
runner.start();
Thread runner_2 = new Thread(new MyThread("second"));
runner_2.start();
System.out.println("Waiting for threads.");
}
}
class MyThread implements Runnable {
String name;
MyThread(String name) {this.name = name;} //constructor
public void run() { //threaded code
int count = 0;
while (count < 10_000) {
if (count % 1000 == 0)
System.out.println(name + " count is: " + count);
count++;
}
}
}Waiting for threads.
second count is: 0
second count is: 1000
first count is: 0
second count is: 2000
first count is: 1000
second count is: 3000
first count is: 2000
second count is: 4000
second count is: 5000
second count is: 6000
first count is: 3000
second count is: 7000
first count is: 4000
second count is: 8000
first count is: 5000
second count is: 9000
first count is: 6000
first count is: 7000
first count is: 8000
first count is: 9000
Process finished with exit code 0example: find the xth prime number
The program takes as command line argument the x th prime number, e.g. 2 and 5 will print the second and fifth prime number.
The
PrimeFinderclass implements theRunnable interface, so it can be run as a thread. There are three public instance variables:-
target:
is alongthat indicates when the specified prime in the sequence has been found. If you’re looking for the 5,000th prime, target equals 5000. -
prime:
is alongthat holds the last prime number found by this class. -
finished:
is aBooleanthat indicates when the target has been reached. -
runner:
Holds the Thread object this class runs in. This object equalsnullbefore the thread is started. -
line 7-13:
The "PrimeFinderconstructor method" sets the "targetinstance variable" and starts the thread if it hasn’t been started. When the thread’sstart()method is called, it in turn calls therun()method of the threaded class. -
line 15-26:
Therun()method does most of the work of the thread. This method uses two new variables:numPrimes, the number of primes that have been found, andcandidate, the number that might possibly be prime. The candidate variable begins at the first possible prime number, which is2. -
line 18-24:
Thewhileloop continues until the right number of primes has been found. First, it checks whether the currentcandidateis prime by calling theisPrime(long)method, which returnstrueif the number is prime andfalseotherwise. If thecandidateis prime,numPrimesincreases by 1, and theprimeinstance variable is set to this prime number. Thecandidatevariable is then incremented by 1, and the loop continues. -
line 25::
After the right number of primes has been found, the while loop ends, and thefinishedinstance variable is set totrue. This indicates that thePrimeFinderobject has found the right prime number and is finished searching. The end of therun()method is reached and the thread no longer does any work. -
line 28-35:
This method determines whether a number is prime by using the%operator, which returns the remainder of a division operation. If a number is evenly divisible by 2 or any higher number (leaving a remainder of 0), it is not a prime number.
public class PrimeFinder implements Runnable {
public long target;
public long prime;
public boolean finished = false;
private Thread runner;
PrimeFinder(long inTarget) {
target = inTarget;
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
public void run() {
long numPrimes = 0;
long candidate = 2;
while (numPrimes < target) {
if (isPrimes(candidate)) {
numPrimes++;
prime = candidate;
}
candidate++;
}
finished = true;
}
boolean isPrimes(long checkNumber) {
double root = Math.sqrt(checkNumber);
for (int i = 2; i <= root; i++) {
if (checkNumber % i == 0)
return false;
}
return true;
}
}- line 8-16:
Converts command line arguments fromStringtolongand starts for each a thread by instantiating aPrimeFinderobject. - line 9-13:
Because arguments areStringobjects, and the "PrimeFinderconstructor" requireslongvalues, theLong.parseLong(String)class method is used to handle the conversion. All the number-parsing methodsthrow NumberFormatExceptionexceptions, so they are enclosed in "try-catch blocks" to deal with arguments that are not numeric. - line 18-28:
Thewhile loopchecks to see whether anyPrimeFinderthread has completed, which is indicated by itsfinishedinstance variable equalingtrue. When a thread has completed, thedisplayResult()method is called in line 25 to display the prime number that was found. The thread then is set tonull, freeing the object’s resources (and preventing its result from being displayed more than once). - line 29-33:
The call toThread.sleep(1000)causes thewhile loopto pause for one second during each pass through the loop. A slowdown in loops helps keep the JVM from executing statements at such a furious pace that it becomes bogged down.
NOTE: commented out because was not necessary.
public class ThreadsTest {
public static void main(String[] args) {
ThreadsTest pt = new ThreadsTest(args);
}
public ThreadsTest(String[] args) {
PrimeFinder[] finder = new PrimeFinder[args.length];
for (int i = 0; i < args.length; i++) {
try {
long count = Long.parseLong(args[i]);
finder[i] = new PrimeFinder(count);
System.out.println("Looking for prime " + count);
} catch (NumberFormatException nfe) {
System.out.println("Error: " + nfe.getMessage());
}
}
boolean complete = false;
while (!complete) {
complete = true;
for (int j = 0; j < finder.length; j++) {
if (finder[j] == null) continue;
if (!finder[j].finished) {
complete = false;
} else {
displayResult(finder[j]);
finder[j] = null;
}
}
// try {
// Thread.sleep(1000);
// } catch (InterruptedException ie) {
// // do nothing
// }
}
}
private void displayResult(PrimeFinder finder) {
System.out.println("Prime " + finder.target + " is " + finder.prime);
}
}Calling the ThreadsTest program with the following command line arguments:
20000 100 4200 30Looking for prime 20000
Looking for prime 100
Looking for prime 4200
Looking for prime 30
Prime 100 is 541
Prime 4200 is 39971
Prime 30 is 113
Prime 20000 is 224737
Process finished with exit code 0 -
Stopping a Thread
The best way to stop a thread is to place a loop in the thread’s run() method that ends when a variable changes in value.
-
A class method,
Thread.currentThread(), returns a reference to the current thread (in other words, the thread in which the object is running). -
The following run() method loops as long as runner and currentThread() refer to the same object:
public void run() {
Thread thisThread = Thread.currentThread();
while (runner == thisThread) {
// body of loop
}
} -
If you use a loop like this, you can stop the thread anywhere in the class with the following statement:
runner = null