Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon
Accepted Solution

Screen update, threading, and synchronization

I have a game that I am developing that uses several threads to process. The game is not user-driven per-se, and seems to speed up when there are more objects on the screen, and slows down when there are fewer. I have four main threads in use. Three of them are used for update by the main thread (UI) and continuously run; two update a custom stop watch class, and the third just invalidates the screen to force redraw. All three of the threads use synchronized object locks; which is why I think it slows down when nothing is on the screen, because they constantly block. I do have variables that are constantly updated by the thread and alse read every iteration; which I was I'm using the locks. I am using the 4.7 IDE and the Storm simulator. Profiling the code over a 3 minute period shows that almost 60% of the execution time is at either of the locked lines (blocking I'm sure). I was wondering do I need to use locks since only the UI thread updates any of the three? If so, is there a better way. Code can be provided if needed.
Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Screen update, threading, and synchronization

[ Edited ]

CPU time or clock time? Normally waiting for a monitor doesn't use CPU but you really should

[ed: NOT , sorry ] design code to wait there, you can use wait notify or something similar as there are more options to

wake up. With a paranoid obsession on safety any pathological behaviours are possible, including

lock starvation at low loading.

 

It may be worth extracting the code and running it on a desktop if you can easily stub out the

phone specific stuff. I've started doing this and so far seems like a good way to go.

Task manager can often tell you a bit and it is easy to modify timing relationships.

 

 

Message Edited by marchywka on 02-11-2009 09:59 PM
Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Screen update, threading, and synchronization

I don't understand what you are saying. I use system.getTimeMillis() to set the creation time, and constantly poll it to see how much time has elapsed. I use this to update the game clock every cycle. I don't think its using cpu time, but I use synchronized statements to block before reading or updating a value, so any other try to read it blocks until complete. The thread constantly updates it own values (ie time) which is why i put the lock objects in, so I won't try and read while it is writing. I use code like this:

 

public void run(){

   synchronized( object1 ){

      //update value

   }

}

 

 

public int getTime(){

   synchronized( object1 ){

      return time;

   }

}

Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Screen update, threading, and synchronization

for that specific concern, volatile should work on the long time,

 

http://java.sun.com/docs/books/tutorial/essential/concurrency/atomic.html

 

 

Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Screen update, threading, and synchronization

I looked at volatile, but I'm not sure if it would work. It is my understanding that it is only useful for single updates and not for blocks of code. Also java passes by value, so does the value passed refer to the memory referrence or the actual value? I don't think it will make alot of difference because the draw loop takes only a few milliseconds now, but I plan on making some 3D effects and do not know how this will lengthen the draw. Here is the code for my StopWatch class (it is essentially the same for the update thread).

 

public class StopWatch extends Thread {
   private final static int COUNT_UP   = 0;
   private final static int COUNT_DOWN = 1;

   private int type = COUNT_DOWN;
   private int speedFactor = 1;
   private long currentTime;
   private long allowedTime;
   private long elapsedTime;
   private long timeChange;

   private final Object pauseLock = new Object();
   private final Object runLock = new Object();

   private boolean paused = false;
   private boolean running = true;

   public StopWatch(long ticks){
      allowedTime = ticks;
   }

   public StopWatch(int type, long ticks){
      this.type = type;
      allowedTime = ticks;
   }

   public void run(){
      currentTime = System.currentTimeMillis();
      while( true ){
         synchronized( runLock ){
            if( running ){
               synchronized( pauseLock ){
                 if( !paused ){
                    timeChange = ((System.currentTimeMillis() - currentTime) / speedFactor);
                    elapsedTime = elapsedTime + timeChange;
                    currentTime = System.currentTimeMillis();                   
                 } else {
                    currentTime = System.currentTimeMillis();
                 }
               }
            }
         }
      }
   }

   public void pause(){
      synchronized( pauseLock ){
         paused = true;
      }
   }

   public void unpause(){
      synchronized( pauseLock ){
         paused = false;
      }
   }

   public void stop(){
      synchronized( runLock ){
         running = false;
      }
   }

   public void reset(){
      synchronized( runLock ){
         elapsedTime = 0;
      }
   }

   public void addTime(long time){
      synchronized( runLock ){
         allowedTime = allowedTime + time;
      }
   }

   public void removeTime(long time){
      synchronized( runLock ){
         allowedTime = allowedTime - time;
      }
   }

   public void clockFactor(int factor){
      synchronized( runLock ){
         speedFactor = factor;
      }
   }

   public long getTimeMillis(){
      synchronized( runLock ){
         long remainingTime = 0;
         if(type == COUNT_DOWN){
            remainingTime = allowedTime - elapsedTime;
            if( remainingTime < 0 ) remainingTime = 0;
         } else
         if(type == COUNT_UP){
            remainingTime = elapsedTime;
            if( remainingTime > allowedTime ) remainingTime = allowedTime;
         }
         return remainingTime;
      }
   }

}

Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Screen update, threading, and synchronization

[ Edited ]

ROFLMAO- do they have a text book on lock starvation?

 http://java.sun.com/docs/books/tutorial/essential/concurrency/starvelive.html

 

[ ed, I would also point out this seems to be a tight loop so it also uses CPU time spinning

while releasing up to 2 locks only briefly ]

 

while( true ){
         synchronized( runLock ){
            if( running ){
               synchronized( pauseLock ){

Message Edited by marchywka on 02-12-2009 01:13 PM
Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Screen update, threading, and synchronization

I'll look at that. I admit I failed my class on threading the first time and skimmed through the second. LOL.
Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Screen update, threading, and synchronization

Sorry, it is just funny on a number of issues. The time function increment is 1 millisecond, I make

fun of JVM speed too but you may get a lot of repeated values, LOL. At least put in a Thread.sleep(1)

in there so someone else, who doesn't want either of your locks can get a shot.

I guess if you want to time something and use a lock, you could put a wait() in your sync

block and time how long you are there for example.

 

If you just want to make the time read/writes atomic, volatile should work. If you want to get

a consistent set of numbers, put the required operations ( should be simple load store and maybe

aritmetic for read-modify-write) in a single sync block and use a separate object for non-conflicting

operations. Definitely avoid nested synchronization.

 

System calls are never instantaneous and you never know what other locks will get picked up

when you call someone else's code.

Let's say you start overriding methods in a gui class and you end up with the event lock and

just throw in your locks for extra safety. In all liklihood, you will end up with wierd deadlocks

hanging the whole phone gui

that usually only show up when the sponsor downloads the app onto his phone and has to take the

battery out while driving so he can find out if his wife has gone into labor yet etc etc etc.

 

In any case, it is just an interesting simple example.

 

 

 

Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Screen update, threading, and synchronization

Thanks. I used volatile for everything but the updating of the time variables and it speed up a good deal. I don't know if i could get rid of the synchronization on the time updates because I'm using several variables, and doing read-modify-write statements. But it moves a lot faster to start out.
Highlighted
Developer
Posts: 558
Registered: ‎11-25-2008
My Device: Not Specified

Re: Screen update, threading, and synchronization

Just a note. You should do a Thread.sleep(1) or Thread.yield() in there too, as to achieve good thread concurrency you really need the threads to be context switching when appropriate. This is why God invented Mutexes, to block threads and release them at appropriate times. You are doing some of that with your synchronization, but it looks messy. You might actually speed things up by putting in a few sleeps here and there.

 

Good Luck

-Donald