Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (521)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (589)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Threads hanging themselves.  (Read 2047 times)
0 Members and 1 Guest are viewing this topic.
Offline SkyAphid
« Posted 2012-10-12 09:47:13 »

So, I'm making a planet generator. It builds it's continents with perlin noise, and then I run an algorithm I wrote to map out global temperatures based on some photos I viewed of earth's average global temperatures.

So other than that algorithm being pretty bad most of the time, I've got another problem that's coming from Java's threads.

At the end of the standard generation I listed above, I must begin landmark and organism generation and placement. This proved to be very CPU extensive, so I thought it'd be a good idea to make a thread for it instead of trying to execute it all in one step to keep the program from freezing up.

So, essentially, it moves across the map, generating a local map for every tile on a 128x128 map. Each local map is 32x32 tiles. Not too bad, right?

Anyway, it runs, and then around at a y pf 55-59 it stops completely, as in it just stops looping. No errors fire, no exceptions, no crashes, the game runs fine. What this does however, is keep the generator from progressing, which is the problem. Honestly, I have no idea what's going on, I've never had this problem with a thread before.

Here's the code, not that this is the "alpha" code, and has yet to be cleaned up for max efficiency (don't laugh!):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
   Thread threadGenerator = new Thread(){
      public void run(){
                  //Local Maps
         for (int x = 0; x < planetSize; x++){
            for (int y = 0; y < planetSize; y++){
               System.out.println(x+"/"+y);
         
               if (map[x][y][0] != TILE_WATER && map[x][y][0] != TILE_RIVER && map[x][y][0] != TILE_MOUNTAIN){
                  if (map[x][y][1] > 55){
                     if (r.nextInt(2000) < 10){
                        map[x][y][0] = TILE_TOWN;
                        landmarks++;
                     }else if (r.nextInt(5000) < 10){
                        map[x][y][0] = TILE_TOWN_RUINS;
                        landmarks++;
                     }
                  }
                       
                  if (r.nextInt(1500) < 20){
                     map[x][y][0] = TILE_CAVE;
                     landmarks++;
                  }
               }
                     
               localMaps[x][y] = new LocalMap(map[x][y][1], map[x][y][0]);
               localMaps[x][y].generateObjects(r, organisms);
               population+=localMaps[x][y].getLocalPopulation();
                     
               if (population > maxPopulation && limitPopulation){
                  localMaps[x][y].clearPopulation();
                  population = maxPopulation;
               }
            }
         }
      };



Any ideas? I'm dumbfounded.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #1 - Posted 2012-10-12 10:28:36 »

The thead looks kinda odd, using a lot of data outside the scope.
Didnt even know this would really work.
For my planet generation i made a class to do alot of diffrent stuff (implements Runnable).
You just pass some parameters like planet size and leave it alone until its done.

But about the error, finished = true; probably gets triggered, why dont you use a for loop for this, much cleaner i guess.
And these lines are still inside the loop and get triggered 55-59 times, is this supposed to?

done = true;
System.out.println("Done");

I dont know what you do on done = true, but maybe another thread stops it then?
Offline xsvenson
« Reply #2 - Posted 2012-10-12 10:29:24 »

Without submerging myself into the code, I suggest either using a debugger or a a profiler. Debugger can show You the internals of a infinite loop, it can help You determine, why the loop doesn't end.
Profiler will help You, if You have a threadlock.

A debugger comes with any of the big IDEs (eclipse, idea and netbeans).
A profiler comes with the JDK (atleast with oracle jdk), under bin folder with the name "jvisualvm"

Debugger and a profiler is pretty much "must know" tools. They are easy enough to use, google will help You.

“The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet.” - Michael A. Jackson
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DrHalfway
« Reply #3 - Posted 2012-10-12 10:31:34 »

try to make the boolean value volatile, I find that fixes alot of problems in my threads! (then again, I don't use threads much anyway). Its like a programmers trap filled with nightmares.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #4 - Posted 2012-10-12 17:06:26 »

try to make the boolean value volatile, I find that fixes alot of problems in my threads!

If you don't know why, don't screw around with random fixes.  In this case, it's a wildly inappropriate mechanism.  First, Thread has its own completion flag built right in.  Second, if you want to take action or wait on the completion of a thread, you should be using java.util.concurrent.

In fact I'd go so far as to say if you start out with concurrency by typing T-h-r-e-a-d you are doing it wrong
Offline Cero
« Reply #5 - Posted 2012-10-12 19:12:01 »

In fact I'd go so far as to say if you start out with concurrency by typing T-h-r-e-a-d you are doing it wrong

So you so that "extends Thread" is bad and "implements Runnable" would be ok ?

Edit: ah Runnable is not from java.util.concurrent, I guess I have never used that package either than. I only do concurrency rarely but I would use Runnable and make a new thread with a runnable instance as constructor parameter...

Offline matheus23

JGO Kernel


Medals: 112
Projects: 3


You think about my Avatar right now!


« Reply #6 - Posted 2012-10-12 19:42:11 »

In fact I'd go so far as to say if you start out with concurrency by typing T-h-r-e-a-d you are doing it wrong

So you so that "extends Thread" is bad and "implements Runnable" would be ok ?

Edit: ah Runnable is not from java.util.concurrent, I guess I have never used that package either than. I only do concurrency rarely but I would use Runnable and make a new thread with a runnable instance as constructor parameter...

java.util.concurrent is all about Executors and ... stuff, you know? Grin

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline sproingie

JGO Kernel


Medals: 202



« Reply #7 - Posted 2012-10-12 19:49:03 »

Nope, I mean working with java.lang.Thread directly at all.  Obviously at some point you may make use of Thread, but my little epistle was about starting off with it, which is something you don't do any more than you should be starting off your programs by optimizing an opcode dispatch jump table for page locality.  "implements Runnable" is fine, best passed to an ExecutorService to get a Future back, not Thread.  Presto, free thread pooling.  Pass it a callable instead and now you can get results back.  j.u.c. is full of all kinds of goodies, and it's just the start of the high-level concurrency stuff that other libraries build on top of it.


 
Offline SkyAphid
« Reply #8 - Posted 2012-10-12 20:07:14 »

try to make the boolean value volatile, I find that fixes alot of problems in my threads!

If you don't know why, don't screw around with random fixes.  In this case, it's a wildly inappropriate mechanism.  First, Thread has its own completion flag built right in.  Second, if you want to take action or wait on the completion of a thread, you should be using java.util.concurrent.

In fact I'd go so far as to say if you start out with concurrency by typing T-h-r-e-a-d you are doing it wrong

I'm going to check out runnable, but I'll also read up on concurrent like you said I should. The code looks nasty because it's basically a rough draft. Usually I try to make it work, and then I clean it up so that it looks pretty. Just how I am, Hahah.

The thead looks kinda odd, using a lot of data outside the scope.
Didnt even know this would really work.
For my planet generation i made a class to do alot of diffrent stuff (implements Runnable).
You just pass some parameters like planet size and leave it alone until its done.

But about the error, finished = true; probably gets triggered, why dont you use a for loop for this, much cleaner i guess.
And these lines are still inside the loop and get triggered 55-59 times, is this supposed to?

done = true;
System.out.println("Done");

I dont know what you do on done = true, but maybe another thread stops it then?

It works great until it just stops itself. That's the thing, it's supposed to get triggered around 128 times but stops about halfway through for no apparent reason.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #9 - Posted 2012-10-12 21:52:34 »

So why dont you use for(int x = 0; x < planetSize; x++){   }
I dont understand whou your using a while loop, it makes your code alot less readable.

Maybe it stops because you have x < planetsize-1 and  y < planetsize-1, you skipped the last row of the x and y.
your code just creates confusion.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline SkyAphid
« Reply #10 - Posted 2012-10-12 22:53:24 »

So why dont you use for(int x = 0; x < planetSize; x++){   }
I dont understand whou your using a while loop, it makes your code alot less readable.

Maybe it stops because you have x < planetsize-1 and  y < planetsize-1, you skipped the last row of the x and y.
your code just creates confusion.

Yeah, I fixed it by doing this.
I'm really inexperienced with using Threads instead of just While statements, so my dumbass thought a while statement was a must in a Thread.

I can program neural networks to learn how to speak but I can't use a thread, I feel so ignorant! Hahah

Edit:
I'm still getting hangs. I've implemented runnable and tried that as well. It still stops about a quarter in.
I'm going to try concurrent and see what that does.

Edit, Edit:
I used executorService, and it hangs too. Sad

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline SkyAphid
« Reply #11 - Posted 2012-10-12 23:48:17 »

After debugging to see where the thread was deadlocking, I arrived at this point inside the local map generator.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
         if (mapType == MAP_TOWN){
            int tries = 0;
            ArrayList<House> houses = new ArrayList<House>();
            int maximumHouses = r.nextInt(MAXIMUM_HOUSES);
           
            while(houses.size() < maximumHouses && tries < MAXIMUM_HOUSE_PLACE_FAILS){
               House house = new House(r.nextInt(32), r.nextInt(32), 4 + r.nextInt(16), 4 + r.nextInt(16));
               
               for (int a = 0; a < houses.size(); a++){
                  if (house.intersectWith(houses.get(a))){
                     tries++;
                     break;
                  }
               }

                  houses.add(house);
            }
           
            for (int a = 0; a < houses.size(); a++){
               map = houses.get(a).placeHouse(map);
            }
         }


According to the debugger, the locked thread had stopped at this point:

1  
House house = new House(r.nextInt(32), r.nextInt(32), 4 + r.nextInt(16), 4 + r.nextInt(16));


So, is it Random that's killing everything? It's odd because it generates a few houses before this point generally and the House constructor just sets its values to the ones passed in. I've tried slowing down the thread and it still inevitably freezes over.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline Geemili

Senior Devvie


Medals: 9
Projects: 1
Exp: 2 years


No Games Finished


« Reply #12 - Posted 2012-10-12 23:51:39 »

Have you tried removing the randoms?
Offline SkyAphid
« Reply #13 - Posted 2012-10-13 00:24:28 »

Have you tried removing the randoms?
Yes, and it works fine when I do.

Edit: I managed to fix it. It was a problem with my loop. I replaced the one above with the one that works.

It seemed that Java wasn't breaking at the right spot, so the loop itself turned into an indefinite loop, holding up the Thread.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xFryIx (58 views)
2014-11-13 12:34:49

digdugdiggy (36 views)
2014-11-12 21:11:50

digdugdiggy (30 views)
2014-11-12 21:10:15

digdugdiggy (24 views)
2014-11-12 21:09:33

kovacsa (48 views)
2014-11-07 19:57:14

TehJavaDev (51 views)
2014-11-03 22:04:50

BurntPizza (51 views)
2014-11-03 18:54:52

moogie (66 views)
2014-11-03 06:22:04

CopyableCougar4 (64 views)
2014-11-01 23:36:41

DarkCart (150 views)
2014-11-01 14:51:03
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!