Results 1 to 3 of 3
  1. #1
    garyksmith is offline Member
    Join Date
    Oct 2011
    Posts
    2
    Rep Power
    0

    Default Java scheduling issue

    I have an example program that shows some very strange behaviour with Java scheduling. I'm running this on the 1.5 Ubuntu linux VM, although I've seen exactly the same issue under Androids VM (which is what prompted me to write a simple test to see if it was just Android's Java VM that was the problem).

    Basically, I have a busy worker thread that spends most of its time inside a synchronized function call. It occasionally drops out (once per second in this case) and returns rapidly. Meanwhile, my main thread is also trying to call a synchronised function in the same class. I would have expected to get alternate calls in this case, but it doesnt seem to happen. The main thread appears to be starved of access to this class and only occsaionally seems to get into this class. I can get hundreds of back to back calls to doWork() without a single access to poke() getting through.

    If anyone can shed some light onto what mechanisms Java is using in this case and perhaps how to avoid it (yield in the run() function doesnt help, sleep 1 helps a little, sleep 10 helps significantly more - but I cant delay the main loop of the app by 10ms every loop!).

    Java Code:
    package com.test.javaschedule;
    
    public class JavaThread extends Thread {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            JavaThread javathread = new JavaThread();
            
            javathread.start();
            
            while (true)
            {
                javathread.poke();
            }        
    
        }
        
        boolean lastWasPoke = false;
        long    iterations = 0;
        
        synchronized void poke()
        {
            if (lastWasPoke == false)
            {
                System.out.println("First Poke after " + iterations +" works!");
                iterations = 0;
                lastWasPoke = true;
            }
            iterations++;
        }
        
        synchronized void doWork()
        {
            if (lastWasPoke == true)
            {
                System.out.println("First work after " + iterations +" pokes!");
                iterations = 0;
                lastWasPoke = false;
            }
            iterations++;
            
            long endTime = System.currentTimeMillis() + 1000;
            
            while (System.currentTimeMillis() < endTime)
            {
            }
        }
    
        @Override
        public void run() {
            while (true)
            {
                doWork();
                
                // Commenting out the following print pretty much guarantees that poke will never succeed.
                System.out.println("No longer in Synchronize");
            }
    
        }
    
    }

  2. #2
    Dark-Redd is offline Member
    Join Date
    Oct 2011
    Posts
    19
    Rep Power
    0

    Default Re: Java scheduling issue

    Quote Originally Posted by garyksmith View Post
    I have an example program that shows some very strange behaviour with Java scheduling. I'm running this on the 1.5 Ubuntu linux VM, although I've seen exactly the same issue under Androids VM (which is what prompted me to write a simple test to see if it was just Android's Java VM that was the problem).

    Basically, I have a busy worker thread that spends most of its time inside a synchronized function call. It occasionally drops out (once per second in this case) and returns rapidly. Meanwhile, my main thread is also trying to call a synchronised function in the same class. I would have expected to get alternate calls in this case, but it doesnt seem to happen. The main thread appears to be starved of access to this class and only occsaionally seems to get into this class. I can get hundreds of back to back calls to doWork() without a single access to poke() getting through.

    If anyone can shed some light onto what mechanisms Java is using in this case and perhaps how to avoid it (yield in the run() function doesnt help, sleep 1 helps a little, sleep 10 helps significantly more - but I cant delay the main loop of the app by 10ms every loop!).

    Java Code:
    package com.test.javaschedule;
    
    public class JavaThread extends Thread {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            JavaThread javathread = new JavaThread();
            
            javathread.start();
            
            while (true)
            {
                javathread.poke();
            }        
    
        }
        
        boolean lastWasPoke = false;
        long    iterations = 0;
        
        synchronized void poke()
        {
            if (lastWasPoke == false)
            {
                System.out.println("First Poke after " + iterations +" works!");
                iterations = 0;
                lastWasPoke = true;
            }
            iterations++;
        }
        
        synchronized void doWork()
        {
            if (lastWasPoke == true)
            {
                System.out.println("First work after " + iterations +" pokes!");
                iterations = 0;
                lastWasPoke = false;
            }
            iterations++;
            
            long endTime = System.currentTimeMillis() + 1000;
            
            while (System.currentTimeMillis() < endTime)
            {
            }
        }
    
        @Override
        public void run() {
            while (true)
            {
                doWork();
                
                // Commenting out the following print pretty much guarantees that poke will never succeed.
                System.out.println("No longer in Synchronize");
            }
    
        }
    
    }
    Hi,

    I am not sure, but I see you have no conditions within your loops that will terminate at some point.
    I think of you can use the
    Java Code:
    wait()
    method it might help since your synchronizing your methods.
    Please re-consider you conditional statements they can have an effect on the output.

    Regards
    Dark-Redd

  3. #3
    garyksmith is offline Member
    Join Date
    Oct 2011
    Posts
    2
    Rep Power
    0

    Default Re: Java scheduling issue

    I've done a good deal of digging and have actually solved this issue now. Details below.

    I am not sure, but I see you have no conditions within your loops that will terminate at some point.
    I think of you can use the
    wait()
    method it might help since your synchronizing your methods.
    Please re-consider you conditional statements they can have an effect on the output.
    The synchronized method is implicitly a lock and unlock of some kind. It basically states that only one thread may be inside any sychronized method of a particular object at any time. So, the code is technically just fine and if synchronised was implemented as a standard os mutex, the code would generally work as I'd expected. But, this definition of synchronized is the issue. It doesnt specify any order in which to resolve contention and hence its implementation specific as to how they implement synchronized.

    In my real case (rather than my test case above that runs on linux), this is running on the Android VM. Its synchronization is achieved by using two different lock types. A fat lock and a thin lock. By default, all objects get a thin lock - which is a high performance lock thats really quick when there is little or no contention. A fat lock is a standard mutex with a queue of people waiting so that threads waiting get woken up as soon as another thread leaves the mutex. Running the above app on a fat lock works as expected with several pokes then one wait and several more pokes and one wait etc. Running it on a thin lock results in starvation of the poke thread.

    As soon as a thin lock detects contention, it upgrades the thin lock to a fat lock. The problem is, the upgrade needs to acquire the thin lock before it can upgrade the lock. The code to upgrade the lock isnt that great. It simply polls the lock state with an increasing backoff period (up to 1 second of sleep between polls). Hence, if you have a thread thats holding onto the lock 99%+ of the time and only releasing it briefly, that poll will almost always return that the lock is acquired by someone else and you have starvation.

    Not sure what the situation is in the linux VM - presumably its something similar.

    In summary of this, dont use synchronize if you have any threads that will be in the synchronized section for large periods of time. Use mutexes or semaphores instead.
    Last edited by garyksmith; 10-12-2011 at 11:52 AM.

Similar Threads

  1. First JAVA project: scheduling system
    By dee-u in forum New To Java
    Replies: 18
    Last Post: 06-29-2011, 09:59 AM
  2. Job Scheduling in java
    By umapathy_sekar in forum Advanced Java
    Replies: 2
    Last Post: 09-13-2010, 05:27 PM
  3. Job scheduling using timers in java
    By umapathy_sekar in forum New To Java
    Replies: 1
    Last Post: 09-13-2010, 05:18 PM
  4. * Help: Java Code For Cpu Scheduling Algorithm
    By coldvoice05 in forum AWT / Swing
    Replies: 2
    Last Post: 03-10-2010, 03:43 PM
  5. * Help: Java Code For Cpu Scheduling Algorithm
    By coldvoice05 in forum New To Java
    Replies: 1
    Last Post: 07-15-2009, 04:30 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •