Reputation: 6752
When I try to use methods inside a class in which I extend Thread
it does not receive the methods after the run.
My class:
public class PassPhraseValidator<E> extends Thread {
private List<E> list;
private boolean isValid;
private String passPhrase;
public PassPhraseValidator(List<E> list) {
this.list = list;
}
public String getPassPhrase() {
return passPhrase;
}
public boolean isValid() {
return isValid;
}
public void run(){
this.passPhrase = Arrays.toString(list.toArray());
this.isValid = list.stream().filter(e -> Collections.frequency(list, e) > 1).count() == 0;
}
}
So when I execute this class like this:
PassPhraseValidator<Integer> validIntegerPassPhrase = new PassPhraseValidator<>(Arrays.asList(12, 18, 15, 32));
validIntegerPassPhrase.start();
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
It gives me false while it should be true because the run function wasn't ran yet.
What am I doing wrong here? How can I make multithreading part of this? It does work when I directly put it inside the methods.
Upvotes: 1
Views: 66
Reputation: 1132
Explanation
What you are doing is called multithreading. This allows multiple threads to execute code concurrency or in parallel. Programs run on something called the main thread. This means one thread is executing all code systematically; one instruction after another. When introducing another thread like you are, the program execution is being done on different logic at the same time. So, when you execute the start()
method on your implementation of the thread
class, you are causing it to execute it's respective run()
method in the background until; it completes, an exception is thrown, the application is shutdown, or the thread is stopped.
Lets step through your code and analyze the scenario.
Thread object is instantiated by the main thread
. Lets call this new thread thread2
.
thread2
is started by the main thread
.
thread2
and the main thread
are both running in parallel. This means code is being executed by both of them (for simplicity) at the same time.
Two possibilities could be occurring for this issue; Java Memory Barrier (beyond the scope of this question but more reference here) or timing. The main thread
is most likely reading the print statement before thread2
can finish it's respective run()
method.
Solution
An approach may be not to use multi-threading at all. The creation of threads is quite a costly operation and should not be done frequently. Typically, in app's that require multi-threading thread-pools are utilized instead.
Utilize the join()
blocking function. Join forces the calling thread (in this case it would be the main thread
) to wait for the respective thread to finish execution before continuation.
Implement the thread with use of Promise
. This object is a wrapper for the Future
class, allowing for the get()
method to be blocking. This means the calling thread (in this case it would be the main thread
) to wait for the respective thread to finish execution before continuation. An example of Promise
's can be found here.
Upvotes: 1
Reputation: 17920
The last System.out.println
statement does not wait for your thread (the run
function) to complete.
One way to wait for its completion is to call the join
method
validIntegerPassPhrase.join(); //Need to handle the InterruptedException it might throw
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
Upvotes: 1