UPDATE:
Turns out that I was initializing my inputstream on both my Server and Client at the same time and that was what was causing the problem.
In the server side of an application I am making: I never reach one part of the code, which causes my client end to block at that point. Initially I assumed there weren't enough resources for it to run the program, so I quit all my other applications and tried again. I left it running for an hour, still to no avail.
How can I figure out what's wrong? I can't understand where it might be blocking and it can't be stuck in an infinite loop anywhere before that point.
String[][] coordinates1 = new String[10][10], coordinates2 = new String[10][10];
public void run() {
//initializes the 10x10 grids for the player
synchronized (this) {
//outer loop is for the rows
for (int loop = 0; loop < 10; loop++) {
//the inner loop is for the columns
for (int loop2 = 0; loop2 < 10; loop2++) {
coordinates1[loop][loop2] = "~ ";
coordinates2[loop][loop2] = "~ ";
}
}
}
if (player == 1) {
//deals with the client assuming it is player1
//declares Object i/o streams
ObjectInputStream in = null;
ObjectOutputStream out = null;
try {
//initializes i/o streams
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputStream(client.getOutputStream());
//writes the two 10x10 grids to the client
out.writeObject(coordinates2);
out.writeObject(coordinates1);
out.flush();
...
}
The part it never reaches are the "out.writeObject(..);" lines.
The full code can be found here, along with the client end.
It is not blocked, your program is waiting.
You never get to the writeObject line, because the preceeding two lines (getInputStream and getOutputStream) will "wait" for the socket to establish a valid connection. You can verify this by placing two log lines around this:
in = new ObjectInputStream(client.getInputStream());
To fix the problem I would suggest reviewing your code where you are establishing the connection (ServerSockets and Sockets).
Related
The code below works fine, however I want value to reach the end of the array, as at the moment it start from 1 then goes to the end of the array.
Booth[] boot = new Booth[numberOfBooths];
for (int j = 1; j < boot.length; j++) {
boot[j] = new Booth(j, buff);
boot[j].start();
}
for (int j =1 ; j < boot.length; j++) {
try {
boot[j].join();
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
I altered the code so the loops start from 0.. such:
for (int j = 0; j < boot.length; j++) {
boot[j] = new Booth(j, buff);
boot[j].start();
}
for (int j =0 ; j < boot.length; j++) {
try {
boot[j].join();
} catch (InterruptedException ex) {
System.out.println(ex);
}
But after debugging as soon as it gets to the join the program stops. I read about Deadlock and maybe that was the reason for this, could there be a way around it, is there a general solution to this problem?
Edit: Sorry I haven't been so clear. The code works either way, however when I run it a second time ( I have my program in a while loop ) it doesn't do the join
It sounds as if the thread pointed to by boot[1] completes, but the thread pointed to by boot[0] does not.
Therefore something about new Booth(0,buff) creates an object for which run() doesn't terminate.
Try unit testing Booth without using threads, and just run:
Booth b = new Booth(0,buff); // initialise buff first, of course
b.run();
... and see whether this returns. If not, work out why, perhaps by stepping through it with a debugger.
The other thing to look out for is deadlock around the shared buff object. Unless there is some locking around buff, you can certainly expect issues. However that seems less likely if starting your index at 1 solves the problem.
If the whole thing works the first time around, but not on a second attempt, then you should consider the state of buff. Perhaps new Booth(0,buff).run() is non-terminating when supplied a certain state of buff.
Aside: It's cleaner to not do class Booth extends Thread but instead class Booth implements Runnable.
Then instead of Booth.start() use
Thread t = new Thread(booth);
t.start();
That way you're not polluting the Booth code with the knowledge that it's going to be a thread -- it's better encapsulation.
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 am trying to submit solution (using some online compiler that has compile time constraints) for sorting an array- here is my code snippet-
class TSORT {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter bw = new PrintWriter(System.out, false);
int t = Integer.parseInt(br.readLine());
int[] list = new int[1000001];
for(int i = 0; i < t; i++){
int n = Integer.parseInt(br.readLine());
list[n]++;
}
int r=0;
for(int i = 0; i < 1000001; i++){
if(list[i] > 0){
for(int j = 0; j < list[i]; j++){
bw.println(i); // if I use bw.flush() here, time limit gets exceeded.
}
}
}
bw.flush();
}
}
This code gets submitted successfully, but if I use flush() as true (automatic flushing- new PrintWriter(System.out, true);), the compiler shows TIME LIMIT EXCEEDED .
My question is - how should I use flush() to get best compile time?
You're submitting the code, and it is afterwards executed somewhere, that's why you have a TIme Limit Exceeded exception.
The reason why you don't get this exception if you disable automatic flushing is simple, once you look at what flush actually means. flush blocks your code and waits until everything which was written to the stream also went through the stream to it's target (in this case System.out).
If you have automatic flushing turned on, it will flush after every println command. So after every println you application blocks and waits for the Java VM or the Host system to forward your string to System.out.
If you have automatic flushing turned off, the strings of println are cached in memory. Depending of the implementation of the stream, it can still try to flush out data from the memory in the background, but it doesn't have to. In the end of your application you will write all your strings at once (via flush). This is faster because of less context switches and because it doesn't lock your application from running the loop.
I have an application which is quite resource intensive, it is using large images as input and some of the operations on these images can take a while. I am therefore looking to make some parts run in their own threads. To do this I have used the following code just to test out first:
Thread t1 = new Thread(new Runnable() {
public void run()
{
inputChooser.setFileFilter(filter);
inputChooser.addChoosableFileFilter(filter);
int img = inputChooser.showOpenDialog(this);
if (img == JFileChooser.APPROVE_OPTION) {
File file = inputChooser.getSelectedFile();
String filename = file.getName();
if (filename.contains("B10")) {
greenBand = 1;
}
if (filename.contains("B20")) {
greenBand = 2;
}
if (filename.contains("B30")) {
greenBand = 3;
}
if (filename.contains("B40")) {
greenBand = 4;
}
if (filename.contains("B50")) {
greenBand = 5;
}
if (filename.contains("B60")) {
greenBand = 6;
}
if (filename.contains("B70")) {
greenBand = 7;
}
try {
greenImage = ImageIO.read(file);
ImageIO.write(greenImage, "JPEG", new File("img2_tmp.jpeg"));
greenImage = ImageIO.read(new File("img2_tmp.jpeg"));
if (greenImage.getWidth() > 8000 | greenImage.getHeight() > 7000) {
greenImage = greenImage.getSubimage(1450, 1400, (greenImage.getWidth()-3200), (greenImage.getHeight()-3000));
}
update(greenImage, greenIcon, greenLabel);
loadingBar.setIndeterminate(false);
checkInput();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Input Image Error", "Input Error", WARNING_MESSAGE);
}
}
}});
t1.start();
When I run the application it freezes when this code is called. However, I have managed to get it to work once, I am not sure how but it ran perfectly (not the first time, it froze a few times first and then randomly worked one time). I haven't changed any of the code just some of the indents and such to get it to fit with the rest of the code and ever since it just continues to freeze. A button action press calls this method where the above code is, as soon as the buttons pressed it freezes.
Is there a reason as to why this is happening?
Thanks in advance
You are calling a non-thread-safe code (swing (is NOT thread safe)) from both threads (newly created and main thread) at the same time.
Make sure that you have decoupled the logic before creating new threads.
For this specific use case, I'd suggest that you use SwingWorkers in stead of threads, they are easy to use, and work well within the limitations of swing.
More about SwingWorkers at http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Hope this helps.
Good luck.
It's difficult to say exactly, but I notice that the variable greenImage and greenBand are not declared anywhere. That makes me think they are global variables. If something else has access to them, it's possible that they're causing some manipulation that sends your code into an infinite loop or does other unexpected Bad Things.
I wrote a simple code that uses multiple threads to calculate number of primes from 1 to N.
public static void main (String[] args) throws InterruptedException
{
Date start;
start = new Date();
long startms = start.getTime();
int number_primes = 0, number_threads =0;
number_primes = Integer.parseInt(args[0]);
number_threads = Integer.parseInt(args[1]);
MakeThread[] mt = new MakeThread[number_threads];
for(int i=1;i<=number_threads;i++)
{
mt[i-1] = new MakeThread(i,(i-1)*(number_primes/number_threads),i*(number_primes/number_threads));
mt[i-1].start();
}
for(int i=1;i<number_threads;i++)
{
mt[i-1].join();
}
Date end = new Date();
long endms = end.getTime();
System.out.println("Time taken = "+(endms-startms));
}
}
As show in above, I want the final time taken to be displayed (just to measure performance for different inputs). However I noticed that when I enter a really big value of N and assign only 1 or 2 threads, the scheduler seems to override the join functionality (i.e the last print statement is displayed before other threads end). Is the kernel allowed to do this? Or do I have some bug in my code?
P.S: I have only shown a part of my code. I have a similar System.out.println at the end of the function that the newly forked threads call.
Your loop is the problem.
for(int i=1;i<number_threads;i++)
{
mt[i-1].join();
}
Either you change the condition to <= or you make a less cryptic loop like this:
for(int i=0; i < number_threads;i++){
mt[i].join();
}
Or a for each loop:
for(MakeThread thread : mt)
thread.join();
Provided you correct your loop which calls join on all threads as shown below
for(int i=0;i<number_threads;i++)
{
mt[i].join();
}
there is no way that the last print line may get invoked before all threads ( as specified in the loop ) finish running and join the main thread. Scheduler cannot make any assumptions with this semantics. As pointed by Thomas , the bug is there in your code that does not call join on the last thread ( which therefore does not complete before the last print is called ).