I'm solving a multi-threaded problem in Java and have the core problem itself resolved, but my output isn't what I'd expect.
I have a main thread that spins new threads that each perform their tasks. It looks like the following (pseudocode):
initializeThreads(); // Creates the new threads
startThreads(); // Starts the new threads
sleep( duration ); // Lets the threads run for `duration` time
shutdownThreads(); // interrupt the threads
printOutput(); // output the results to the console
// definition of shutdownThreads() is at the end of my question
My issue happens upon trying to join() on each thread in my list of threads. Every now and then my program gets caught in an endless loop because I'm guessing the interrupt() I call on my list of threads doesn't happen fast enough compared to the join() and not all the threads get interrupted.
My other issue occurs when the program does shutdown the threads correctly and print the termination output. While the program is running each thread has messages that it logs to the console, and after I interrupt the threads and display the final program message some of these thread-specific logging messages leak out to the console.
For example, let's say one of my threads outputs "Thread-1 waiting for lock on object..." while it runs, and the main program finally wakes itself up, terminates the thread, and outputs "Program finished". Sometimes, the thread-specific message will show up after the program termination message.
If anyone could help me figure out how to stop this from happening please let me know!
shutdownThreads()
private void shutdownThreads() {
Thread t;
for (int i = 0; i < threads.size(); i++) {
t = threads.get(i);
t.interrupt();
}
for (int i = 0; i < threads.size(); i++) {
t = threads.get(i);
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Interrupted while waiting on thread to exit");
}
}
}
EDIT: One thing I thought of doing is rewriting shutdownThreads() to do this:
for (int i = 0; i < threads.size(); i++) {
Thread t = threads.get(i);
t.interrupt();
while (!t.isInterrupted()) ;
}
but this doesn't seem too elegant.
Your edited code at the bottom, that's gonna be a forever loop before it iterates the for() twice.
Related
i need some help with threads , i need to make a program that will close and open threads dynamically ( meaning when i need a thread it will run, if its no longer needed it will stop ) ,
Now my questions is? is k if i only terminate the run method of that thread , does it count as the thread stopping, or how exactly do a close a thread .
public void run() {
while(!tasks.isEmpty()) {
try {
if(tasks.peek() != null) {
Thread.sleep(1000);
waitingPeriod.getAndAdd(-1);
tasks.peek().setProcessingTime(tasks.peek().getProcessingTime() - 1);
if(tasks.peek().getProcessingTime() == 0) {
// System.out.println("Removed task " + tasks.peek().getId() + " from queue" );
tasks.remove();
Thread.currentThread().interrupt();
continue;
}
}
}
catch(InterruptedException e) {
}
//take next task from queue
//stop the thread for a time equal with the task's processing time
//decrement the waitingPeriod
}
}
This threads works over a queue , if there are elements in it i start it from another class, and i want this thread to run only if i have elements, so when the queue empties i want the thread to stop.
how do i stop the thread , is enough to terminate the run function with that while?
Background
So I'm writing an application that aims to perform Monte Carlo simulations to investigate graphs that can evolve via the Moran process (evolutionary graph theory). For un-directed graphs this works perfectly but for directed graphs the application has been exhibiting strange behaviour and I can't for the life of me figure out why. What seems to happen is that when this Boolean variable isDirected is set to true, the threads exit the for loop they run in before the loop condition is met, despite working properly when isDirected is false.
The graphs are represented by an adjacency matrix so the only difference in the code when the graph is directed is that the adjacency matrix is non-symmetric, but I can't see any reason that would have an impact.
Code
The main relevant code is this section from the controller:
//Initialise a threadPool and an array of investigators to provide each thread with an Investigator runnable
long startTime = System.nanoTime();
int numThreads = 4;
Investigator[] invArray = new Investigator[numThreads];
ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
//Assign the tasks to the threads
for(int i=0;i<numThreads;i++){
invArray[i] = new Investigator(vertLimit,iterations,graphNumber/numThreads,isDirected,mutantFitness,vertFloor);
threadPool.submit(invArray[i]);
}
threadPool.shutdown();
//Wait till all the threads are finished, note this could cause the application to hang for the user if the threads deadlock
try{
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}catch(InterruptedException except){
System.out.println("Thread interrupted");
}
//The next two blocks average the results of the different threads into 1 array
double[] meanArray = new double[vertLimit];
double[] meanError = new double[vertLimit];
double[] fixProbArray = new double[vertLimit];
double[] fixProbError = new double[vertLimit];
for(int x=0;x<vertLimit;x++){
for(Investigator i:invArray){
meanArray[x] += i.getMeanArray()[x];
meanError[x] += Math.pow(i.getMeanError()[x], 2);
fixProbArray[x] += i.getFixProbArray()[x];
fixProbError[x] += Math.pow(i.getFixProbError()[x], 2);
}
meanArray[x] = meanArray[x]/numThreads;
fixProbArray[x] = fixProbArray[x]/numThreads;
meanError[x] = Math.sqrt(meanError[x]);
fixProbError[x] = Math.sqrt(fixProbError[x]);
}
long endTime = System.nanoTime();
//The remaining code is for printing and producing graphs of the results
As well as the Investigator class, the important parts of which are shown below:
public class Investigator implements Runnable{
public Investigator(int vertLimit,int iterations,int graphNumber,Boolean isDirected,int mutantFitness,int... vertFloor){
//Constructor just initialises all the class variables passed in
}
public void run(){
GraphGenerator g = new GraphGenerator();
Statistics stats = new Statistics();
//The outer loop iterates through graphs with increasing number of vertices, this is the problematic loop that exits too early
for(int x = vertFloor>2?vertFloor:2; x < vertLimit; x++){
System.out.println("Current vertex amount: " + x);
double[] currentMean = new double[graphNumber];
double[] currentMeanErr = new double[graphNumber];
double[] currentFixProb = new double[graphNumber];
double[] currentFixProbErr = new double[graphNumber];
//This loop generates the required number of graphs of the given vertex number and performs a simulation on each one
for(int y=0;y<graphNumber;y++){
Simulator s = new Simulator();
matrix = g.randomGraph(x, isDirected, mutantFitness);
s.moranSimulation(iterations, matrix);
currentMean[y] = stats.freqMean(s.getFixationTimes());
currentMeanErr[y] = stats.freqStandError(s.getFixationTimes());
currentFixProb[y] = s.getFixationProb();
currentFixProbErr[y] = stats.binomialStandardError(s.getFixationProb(), iterations);
}
meanArray[x] = Arrays.stream(currentMean).sum()/currentMean.length;
meanError[x] = Math.sqrt(Arrays.stream(currentMeanErr).map(i -> i*i).sum());
fixProbArray[x] = Arrays.stream(currentFixProb).sum()/currentFixProb.length;
fixProbError[x] = Math.sqrt(Arrays.stream(currentFixProbErr).map(i -> i*i).sum());;
}
}
//A number of getter methods also provided here
}
Problem
I've put in some print statements to work out what's going on and for some reason when I set isDirected to true the threads are finishing before x reaches the vertLimit (which I've checked is indeed the value I specified). I've tried manually using my GraphGenerator.randomGraph() method for a directed graph and it is giving the correct output as well as testing Simulator.moranSimulation() which also works fine for directed graphs when called manually and I'm not getting a thread interruption caught by my catch block so that's not the issue either.
For the same set of parameters the threads are finishing at different stages seemingly randomly, sometimes they are all on the same value of x when they stop, sometimes some of the threads will have gotten further than the others but that changes from run to run.
I'm completely stumped here and would really appreciate some help, thanks.
When tasks are being run by an ExecutorService, they can sometimes appear to end prematurely if an unhandled exception is thrown.
Each time you call .submit(Runnable) or .submit(Callable) you get a Future object back that represents the eventual completion of the task. The Future object has a .get() method that will return the result of the task when it is complete. Calling this method will block until that result is available. Also, if the task throws an exception that is not otherwise handled by your task code, the call to .get() will throw an ExecutionException which will wrap the actual thrown exception.
If your code is exiting prematurely due to an unhandled exception, call .get() on each Future object you get when you submit the task for execution (after you have submitted all the tasks you wish to) and catch any ExecutionExceptions that happen to be thrown to figure out what the actual underlying problem is.
It looks like you might be terminating the threads prematurely with threadPool.shutdown();
From the Docs:
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.
The code invokes .shutdown before awaitTermination...
I have 8 threads which each execute loops similar to this in their run method:
for (int i = 0; i < someVar; i++) {
for (int j = 0; j < someOtherVar; j++) {
if (Thread.currentThread().isInterrupted()) {
return;
}
// another loop and some calculations here
}
}
I start the Threads like this:
executor = Executors.newFixedThreadPool(threads);
// generate the threads and run them
for (int i = 0; i < threads; i++) {
MyClass cls = new MyClass(i);
executor.execute(cls);
}
Now I need to be able to pretty much instantly kill my threads, that's why I added the if statement above and use at another point executor.shutdownNow(). But it just isn't working fast enough. Some calculations might take a few seconds before they finish and the next iteration starts.
Is there any other reliable way to pretty much immediately shutdown threads?
You need an interrupt operation that calls into the thread and stops the current execution. Here's some documentation: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
Here is a sample code if the thread size is 3 means its ok. where i can manage the memory. if the thread size is 50 there the problem lies. i need to set threadsize as 5. finished thread should be reuse the by other
Thread[] TCreate = new Thread[iThreadSize];
for (int i = 0; i< TCreate.length; i++) {
TCreate[i] = new Thread(new Runnable() {
public void run() {
lst.Add(this.getResult(url));
}
});
TCreate[i].setName("URL"+i);
TCreate[i].start(); }
for (int j = 0; j < TCreate.length; j++)
while (TCreate[j].isAlive())
Thread.sleep(10);
Can any one help what is use of setDaemon() method. what is purpose of Daemon
Please Help me.. Advance thanks
setDaemon controls whether a thread is a daemon thread or not. If daemon threads are still running when the program reaches the end of the main method, it does not keep the program from quitting. Non-daemon threads (user threads) do keep the program from quitting.
Java already includes methods for managing Thread pools.
calling Executors.newFixedThreadPool(5) will generate a thread pool with 5 worker threads for you.
Afterwards you can just assign Runnables that will be executed by on of the Threads in the pool.
See also:
How to implement simple threading with a fixed number of worker threads
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
I am preparing for interviews and just want to prepare some basic threading examples and structures so that I can use them during my white board coding if I have to.
I was reading about CyclicBarrier and was just trying my hands at it, so I wrote a very simple code:
import java.util.concurrent.CyclicBarrier;
public class Threads
{
/**
* #param args
*/
public static void main(String[] args)
{
// ******************************************************************
// Using CyclicBarrier to make all threads wait at a point until all
// threads reach there
// ******************************************************************
barrier = new CyclicBarrier(N);
for (int i = 0; i < N; ++i)
{
new Thread(new CyclicBarrierWorker()).start();
}
// ******************************************************************
}
static class CyclicBarrierWorker implements Runnable
{
public void run()
{
try
{
long id = Thread.currentThread().getId();
System.out.println("I am thread " + id + " and I am waiting for my friends to arrive");
// Do Something in the Thread
Thread.sleep(1000*(int)(4*Math.random()*10));
// Now Wait till all the thread reaches this point
barrier.await();
}
catch (Exception e)
{
e.printStackTrace();
}
//Now do whatever else after all threads are released
long id1 = Thread.currentThread().getId();
System.out.println("Thread:"+id1+" We all got released ..hurray!!");
System.out.println("We all got released ..hurray!!");
}
}
final static int N = 4;
static CyclicBarrier barrier = null;
}
You can copy paste it as is and run in your compiler.
What I want to verify is that indeed all threads wait at this point in code:
barrier.await();
I put some wait and was hoping that I would see 4 statements appear one after other in a sequential fashion on the console, followed by 'outburst' of "released..hurray" statement. But I am seeing outburst of all the statements together no matter what I select as the sleep.
Am I missing something here ?
Thanks
P.S: Is there an online editor like http://codepad.org/F01xIhLl where I can just put Java code and hit a button to run a throw away code ? . I found some which require some configuration before I can run any code.
The code looks fine, but it might be more enlightening to write to System.out before the sleep. Consider this in run():
long id = Thread.currentThread().getId();
System.out.println("I am thread " + id + " and I am waiting for my friends to arrive");
// Do Something in the Thread
Thread.sleep(1000*8);
On my machine, I still see a burst, but it is clear that the threads are blocked on the barrier.
if you want to avoid the first burst use a random in the sleep
Thread.sleep(1000*(int)(8*Math.rand()));
I put some wait and was hoping that I
would see 4 statements appear one
after other in a sequential fashion on
the console, followed by 'outburst' of
"released..hurray" statement. But I am
seeing outburst of all the statements
together no matter what I select as
the sleep.
The behavior I'm observing is that all the threads created, sleep for approximately the same amount of time. Remember that other threads can perform their work in the interim, and will therefore get scheduled; since all threads created sleep for the same amount of time, there is very little difference between the instants of time when the System.out.println calls are invoked.
Edit: The other answer of sleeping of a random amount of time will aid in understanding the concept of a barrier better, for it would guarantee (to some extent) the possibility of multiple threads arriving at the barrier at different instants of time.