12 Replies Latest reply: Nov 13, 2006 2:34 PM by 807607 RSS

    Multi-threading issues with synchronization

    807607
      New to Java...

      I am writing an application that creates mulitple threads. Basically I have a game where you have a main character which runs in the main thread based on keyboard input, then there are monsters which each have their own seperate threads. I am running into problems where one thread sets a value on the hero, possibly exits, and another thread might start up and potentially unset this value. I have read about sychronized methods and synchronized code blocks, but this seems only applicable if you want to prevent ONE object from allowing two of it's methods to run simultaneously. I have multiple objects which each have their own thread.

      1) Is there a way to make sure that once you start say method_A() or chunck of code_A that you do not go into another thread until A has finished the portion you designate.

      2) Also another problem I have is each monster object checks periodically to see if the hero is in the same x and y coordinates as it is and if so it eats him. But if I have a lot of objects and hence threads running, this monster may not get a chance to check to see if the hero is on the same spot as him before the hero moves again, so sometimes I can run right through a monster. Any ideas?

      Thanks.
        • 1. Re: Multi-threading issues with synchronization
          807607
          >
          1) Is there a way to make sure that once you start
          say method_A() or chunck of code_A that you do not go
          into another thread until A has finished the portion
          you designate.
          You are on the right track with sychronizied methods. Research that.
          2) Also another problem I have is each monster
          object checks periodically to see if the hero is in
          the same x and y coordinates as it is and if so it
          eats him. But if I have a lot of objects and hence
          threads running, this monster may not get a chance to
          check to see if the hero is on the same spot as him
          before the hero moves again, so sometimes I can run
          right through a monster. Any ideas?
          Don't have them on separate thread. This is going to be a headache for you. Put all the logic on one thread that will loop through the checks and actions for your monsters and hero.
          • 2. Re: Multi-threading issues with synchronization
            807607
            right through a monster. Any ideas?
            on't have them on separate thread. This is going to
            be a headache for you. Put all the logic on one
            thread that will loop through the checks and actions
            for your monsters and hero.
            I'll think about this more tomorrow...But one of the reasons I did it where each Monster has its own thread is to make the application more dynamic. What I mean is, if I have one thread that does something like:
            while(level==one){
                    Monster1.attack()
                    Monster1.isHeroEaten()
                    Monster2.attack()
                    Monster2.isHeroEaten()
                    isLevelBeaten()
                    didHeroStepOnSpecialButton()
                    etc...
            Each level then might have a different number of monsters, and hence I have to change this one thread to have each added monster now start trying every method in the monster class. Or maybe the next level there is only one monster, so I should no longer have Monster2 doing anything since it isn't there. In other words each level has a very different thread that checks all this stuff.

            I added threads for each monster to generalize this, so that all I have to do for each new level is add monsters, and all of the checking methods and 'intelligence' is built into that instance of the new monster.

            I appreciate any advice, of course, because from a design standpoint I have never programmed a game like this before and realize there are certainly ways to make my life easier, and I am probably not choosing the best way to do this. But at the moment to me it seems the route you suggested would mean a major redesign and possibly encountering more problems that my multi-threaded approach has circumvented.

            What do you think?

            Message was edited by:
            steeveesas
            • 3. Re: Multi-threading issues with synchronization
              807607
              This would not be that major of a design change at all, the actions, logic, state, etc. of the monsters would still be the same. They just would be on the same thread.

              As to your question about making it dynamic. Just put all the monsters in a list and randomly select one or more to attack.
              • 4. Re: Multi-threading issues with synchronization
                807607
                New to Java...
                I have read about
                sychronized methods and synchronized code blocks, but
                this seems only applicable if you want to prevent ONE
                object from allowing two of it's methods to run
                simultaneously. I have multiple objects which each
                have their own thread.
                The relationship between objects, threads and monitors is pretty flexible. You can synchronize on any object, not necessarilly the one whose method you are executing.

                This allows you to create protected resources which only one thread can access at a time.

                Take a look, too, at BlockingQueues, which can be extremely helpful in getting threads sorted out. One thread puts items onto a queue for processing by another thread.
                >
                >
                2) Also another problem I have is each monster
                object checks periodically to see if the hero is in
                the same x and y coordinates as it is and if so it
                eats him. But if I have a lot of objects and hence
                threads running, this monster may not get a chance to
                check to see if the hero is on the same spot as him
                before the hero moves again, so sometimes I can run
                right through a monster. Any ideas?
                Why not have the hero check that he hasn't stepped on a monster rather than the other way arround?
                • 5. Re: Multi-threading issues with synchronization
                  807607
                  I have some stuff to think about. I will give feedback tomorrow about which way I am headed...thanks for the tips.

                  Malcolmmc - about the hero checking to see if he steps on a monster, i have thought about that, and may still implement it. the reason I am not doing this at the moment was bc I had these monster threads which move the monsters around so the hero might be standing and not moving and he might get stepped on by a monster. Really I think I should have a check in both threads if I keep multi threads. But again I may try going single thread ...

                  Ill let you know.
                  • 6. Re: Multi-threading issues with synchronization
                    807607
                    I am ashamed to say it, but I have solved all the problems I was having without doing any synchronizing and keeping all the monsters in their own thread. To be honest I really feel like having them in their own thread is the way to go, because knowing all of the details of my program seems to gear my thinking towards this approach. For example one factor is that the monsters are different and they act differently. In certain cases they should be attacking the hero at the 'same' time. So if they are all in one thread, in order to create the illusion of them attacking at the same time their different attack methods would have to be meshed...for example one of the monsters operates in a while loop, so if I didn't mesh the methods he would complete all his moves before the other had a chance to move. But meshing the methods seems to create more of a headache for me. It is hard to explain without you knowing the details.

                    At some point I may find myself needing synchronized methods to do things, but as I already pointed out, I have shamefully gotten around this issue. But then again, this may be the way to go for now.

                    It is an interesting game, one of logic and problem solving skills. Maybe when its done, I'll post a link to it.

                    btw - When I do my build netbeans creates an executable JAR file. But when I double click on the icon, I get a 'Jave Virtual Machine Launcher' error that says 'Fatal exception occured. Program will exit'
                    what's that about?
                    • 7. Re: Multi-threading issues with synchronization
                      807607
                      If you need things to happen at the same time then threads is not the way to go. One monster could take a long time and complete many actions while the other theads randomly are not given as much time.


                      I would suggest the same as before. All the actions happen on one thread. You would loop through every character/monster and have them do one unit of action. Then draw the action. Then repeat.

                      If an attack takes several actions then once it starts attacking it will have to remember it's state. If the monsters have different logic, then they will just be different classes (hopefully extending from a common Monster object or something).

                      Also, this will allow you to make all the moves for that unit in time and only have to check the hero's location (with respect to other monsters) once. Rather than rechecking everytime anything does an action.
                      • 8. Re: Multi-threading issues with synchronization
                        807607
                        maybe you're right...I am starting to see how it could be programmed on a sinlge thread.

                        One thing to consider is: some monsters may move quicker than others(this is currently being done by sleeping for longer or shorter times in each monsters thread) - with one thread which runs in a continuous while loop, I guess if a monster moved 2ce as fast as another, within this loop his move method would get called 2ce as often, but it gets tricky when a monster moves say 7/10 as fast(then one method gets called 7 while the other gets called 10 in the while). I cannot just add a sleep in this single thread bc then it would apply to all monsters and the hero! I might want the hero to move 5 times faster.

                        Then I repaint after each move, not just after one loop iteration.

                        It is quite different, but I can see how it might work.

                        Is this how games are usually coded, I mean there are always multiple solutions in programming, but at some point a program becomes complex enough that you better being doing it the most efficient way or your game collapses.
                        • 9. Re: Multi-threading issues with synchronization
                          807607
                          No you would paint once after each loop iteration.

                          For different speeds of monsters they should have differenct velocities. For example make the slowest monster move one pixel per unit of time. And the hero 5 and and the 7 times faster monster make it move 7.


                          Or make them all move one pixel, but not move every time. For example the slowest monster would move, then wait 10 iterations or whatever to move another pixel.

                          A lot of the movement and velocities you can extract into a higher class and extend it so that you don't have to rewrite it for each monster.
                          • 10. Re: Multi-threading issues with synchronization
                            807607
                            okay. okay. it makes more sense. I will try to code it like this sometime soon.

                            But one more question before I do:

                            Right now the hero is moving on his own thread. His movements are based on keyboard input. Since I added a KeyListener to my JFrame for the arrow keys, I guess this is in the main Swing thread. So if I want one thread to control the hero, and the monsters, and everything else as you are suggesting, would it be in this thread? It seems like NO, bc I want the monsters to be able to move after X loop iteration(as you pointed out last post) and not just when I move the hero.

                            So how do I seperate the KeyListener from this main thread and put it in the one with the hero and the monsters....this question comes from my lack of Java experience.

                            Btw zadok are you a Java programmer for work?
                            • 11. Re: Multi-threading issues with synchronization
                              807607
                              So how do I seperate the KeyListener from this main
                              thread and put it in the one with the hero and the
                              monsters....this question comes from my lack of Java
                              experience.
                              This is a very thoughtful question. One that many people run into by mistake. You are going to want to have all the logic run on a separate thread. The drawling and handling of events you want to keep on together.

                              The SwingUtilties.invokeLater() method might be useful to you if you are not already aware of it. I am not sure how you are drawing it now. There is more than one way.

                              Anyway, since your game logic is on a separate thread than your key listener you are going to want your key listener events to put commands in a queue that the logic thread will poll and handle during each iteration. (Might want to research the Command Pattern).
                              Btw zadok are you a Java programmer for work?
                              Yes, but not games. More business apps, etc.
                              • 12. Re: Multi-threading issues with synchronization
                                807607
                                Well. I am to the point in my single threaded version where I was with my multi threaded version. It all makes sense now and I am glad I implemented it both ways since I learned a lot about both techniques.

                                I guess it is a bit better where all the logic and moves for the different characters happen in 'one time unit'.

                                I thank you zadok for the suggestions.

                                Also I am polling as suggested a move holder variable every time through my main loop in the logic thread. It is working great, everytime a key is hit it goes into this variable and this variable is polled once per iteration. I had to of course make sure the variable is reset at the end of the iteration or else the hero just keeps moving in the direction last traveled.