Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to use multithreading in my game. However, I can't seem to get rid of the sleep.

If I don't it's a blank screen, as there is no time for the computer to actually render the triangleMob as it can't access getArrayList(), in my main class I have a TriangleMob arraylist. If I delay it, then it can access the previousMob and it renders. If I don't, then it's blank screen.

Can I get rid of the delay? Also, is this a bad way to multithread?

Surely, this should be fast. I need multithreading so can you please not suggest not using it.

public class TriangleMob extends Thread implements Runnable {

        private static int count=0;

        private int objectDisplayList;
        private static ArrayList<TriangleMob> previousMob = new ArrayList<TriangleMob>();
        private static ArrayList<TriangleMob> currentMob = new ArrayList<TriangleMob>();
        private static ArrayList<TriangleMob> laterMob = new ArrayList<TriangleMob>();

        private Vector3f position = new Vector3f(0f,0f,0f);
        private Vector3f movement = new Vector3f(0f,0f,0f);



        public TriangleMob()
        {

                // Create the display list
                CreateDisplayList();

                count++;
        }

        public TriangleMob(Vector3f position)
        {

                // Create the display list
                CreateDisplayList();

                this.position = position;
                count++;
        }

        private void CreateDisplayList()
        {
                objectDisplayList = glGenLists(1);
                glNewList(objectDisplayList, GL_COMPILE);
                {
                        double topPoint = 0.75;
                        glBegin(GL_TRIANGLES);
                        glColor4f(1, 1, 0, 1f);
                        glVertex3d(0, topPoint, -5);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(-1, -0.75, -4);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(1, -.75, -4);

                        glColor4f(1, 1, 0, 1f);
                        glVertex3d(0, topPoint, -5);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(1, -0.75, -4);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(1, -0.75, -6);

                        glColor4f(1, 1, 0, 1f);
                        glVertex3d(0, topPoint, -5);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(1, -0.75, -6);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(-1, -.75, -6);

                        glColor4f(1, 1, 0, 1f);
                        glVertex3d(0, topPoint, -5);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(-1, -0.75, -6);
                        glColor4f(0, 0, 1, 1f);
                        glVertex3d(-1, -.75, -4);

                        glEnd();
                        glColor4f(1, 1, 1, 1);
                }
                glEndList();
        }

        public static int getCount() {
                return count;
        }

        public Vector3f getMovement() {
            return movement;
        }

        public Vector3f getPosition() {
            return position;
        }

        public synchronized int getObjectList() {
            return objectDisplayList;
        }

        public synchronized static ArrayList<TriangleMob> getArrayList(){
            if(previousMob != null) {
                return previousMob;
            }

            previousMob.add(new TriangleMob());

            return previousMob;
        }

        public synchronized  void move(Vector3f movement) {

                // If you want to move in all 3 axis
                position.x += movement.x;
                position.y += movement.y;
                position.z += movement.z;

        }

        public synchronized void render() {
            glPushMatrix();

            glTranslatef(-position.x, -position.y, -position.z);

            glCallList(objectDisplayList);

            glPopMatrix();
        }


        public synchronized static void setTriangleMob(ArrayList<TriangleMob> triangleMobSet) {
            laterMob = triangleMobSet;  
        }


        private synchronized void setPreTriangleMob(ArrayList<TriangleMob> currentMob2) {
            previousMob = currentMob2;
        }

        public void run(){
            while(true) {
                if(laterMob == null) {
                    currentMob = laterMob;
                    System.out.println("Copying");
                }


                for(int i=0; i<currentMob.size(); i++) {
                    currentMob.get(i).move(new Vector3f(0.1f,0.01f,0.01f));
                }

                setPreTriangleMob(currentMob);

                try {
                    sleep(1L);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
share|improve this question
    
Multithreading does not automatically make everything faster, and it's not appropriate for all situations. I suggest you read through your code and make sure you know what you're doing and why you're doing it. For example, pay attention to how you're accessing objectDisplayList. Draw your threads out as lines on paper. Then insert the functions in the order they will be called, including the variables they'll access. Be aware of the order things are happening, and if multiple threads are even required. I don't see why you would need multithreading and maybe you'll find that out too. –  Byte56 Jun 27 '13 at 22:41

1 Answer 1

up vote 0 down vote accepted

Your TriangleMob thread starves the render thread. Nice. The Synchronized keyword on a method uses the object the method belongs to as monitor/lock object. This is probably not what your want. You even have synchronized static method. Why? This will use the class object as lock. Very bad.

Only synchronize on objects (better seperate monitor objects) that threads need to share.

Your render thread needs the list of items it should render. Your Mob thread updates this list. Minimize the time the lock is used, so both threads have a chance to access the list.

Also each TriangleMob Object in your example updates and reads the same synchronized static lists, which worsens the thread starvation issue.

Create seperate manager classes for rendering and updating the game state. Each manager has a list of game objects. Then you only need to synchronize when you push the updated game state (read mob list) to the render manager. Better put the updated game state in a shared object from which the render manager reads. The shared object handles the synchronization of its data.

Why even use multithreading? Have you tried a single threaded approach first? Multithreading is notoriously hard and is one of the problem computer science hasn't solved very well yet. You will have to deal with shared state which must be synchronized to avoid concurrent reads and writes. You will run into deadlocks, thread starvation and other nice issues. All issues which are hard to diagnose and fix. Even it works the performance might be worse than a singlethreaded approach due to suboptimal locking (have I mentioned that multithreaded programming is hard? ;-) )

Keep it simple.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.