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
Regular Contributor
devin
Posts: 51
Registered: ‎05-11-2010
My Device: 8900
My Carrier: Rogers
Accepted Solution

Problems accessing data across threads

I have a singleton that has an array that I want to access from multiple threads.  I set the array as volatile and initialize it to some values when the singleton is first created.  When my app starts up, I create a thread that periodiclly checks what the user is doing and adds values to this array.    I have a screen that when it displays, it lists all the values in this array.  The thread and the screen are getting two different instances of the singleton.  The entries added in the thread are not shown on the screen.  Any time the screen displays it shows what the array has when the object is first initialized.  When I debug this, any calls the screen makes to the get the array from the singleton result in it being created again.  Is this not possbile to share data across threads?

 

This is how I create the instance on the singleton:

 

private static volatile DataAccess instance = new DataAccess();

 

 

I created a simple java file that creates three threads and uses the same object I am using in the blackberry app and it all works fine.  Is there something particular aboue Screens that makes them not play nice with threads?

 

Thanks for any suggestions.

Please use plain text.
Developer
simon_hain
Posts: 15,805
Registered: ‎07-29-2008
My Device: Z10 LE
My Carrier: O2 Germany

Re: Problems accessing data across threads

singletons work differently on blackberry as the static context is not shared between application instances.

 

you can use the runtimestore to create a real singleton or to create a shared service, or use global events to communicate between processes.

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
Developer
Ted_Hopp
Posts: 1,305
Registered: ‎01-21-2009
My Device: Not Specified

Re: Problems accessing data across threads

Screens behave the same as any other object when it comes to sharing data across threads. It sounds like this DataAccess object is (supposed to be) a singleton accessed from multiple threads within a single application instance, not something shared across multiple instances. RuntimeStore isn't going to help in that case.

 

I suggest that you post code showing how the various threads are gaining references to the singleton and accessing the contents. I'm concerned that you are using an incorrect model of cross-thread data access. For instance, the volatile modifier is probably wrong (but harmless)--the reference to a DataAccess object shouldn't be changing if it's a singleton.




Solved? click "Accept as solution". Helpful? give kudos by clicking on the star.
Please use plain text.
Regular Contributor
devin
Posts: 51
Registered: ‎05-11-2010
My Device: 8900
My Carrier: Rogers

Re: Problems accessing data across threads

So, Static data is not shared between threads?  This is all within the same application or at least I think it is.  When the blackberry starts up I create the thread that periodicly updates the data then, when a menu button is clicked, the screen tries to display this data, but the static object that the the screen is trying to get the data from is always created a new when access from the screen.

 

 

What I need to do is to be able to update data from a thread and then access it from a Screen.  I made a very simple version of this to show you so we are only looking at the data sharing aspects of it:

 

 

//Thread that updates the data

public class UpdateThread implements Runnable {
    int sleep = 2000;
    int count = 0;
    public void run() {
        try {
            while (true) {
                count++;
                DataAccess.setData("Update from thread" + count);
                Thread.sleep(sleep);
            }
        }
        catch (InterruptedException iex) {
           
        }

    }

}



//Static object that holds the data:

public class DataAccess {
    private volatile static String data;
   
    static {
        data = "first value";
    }
   
    public static synchronized String getData() {
        return data;
    }
   
    public static synchronized void setData (String val) {
        data = val;
    }
   
}



//screen to display the data:

import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;

public class DisplayData extends MainScreen {
   
    public DisplayData () {
        LabelField lbl = new LabelField(DataAccess.getData());
        add(lbl);
       
    }

}

 

 

 

 

 

I have two entry points for my app, and maybe this is where my problem lies, one that runs on startup of the device and another when you click the app icon.  When the deivce starts up I start my UpdateThread and I can see it updating the data.  Then, when I try to display it in the screen it displays the original value.

 

Am I going about this the wrong way?  I will looked into the shared service or global events.  Do you have an example?

 

Thanks.

Please use plain text.
Developer
Ted_Hopp
Posts: 1,305
Registered: ‎01-21-2009
My Device: Not Specified

Re: Problems accessing data across threads

Static data is indeed shared between threads. My apologies if my wording suggested otherwise.

 

I think that you correctly identified the issue: using alternate entry points the way you describe, you probably are running two separate instances of your application. They would not share the same static data.

 

A RIM knowledge base article on using alternate entry points discusses a technique to do what you want and run only a single application instance. Alternatively, you can use the RuntimeStore technique that Simon suggested originally.




Solved? click "Accept as solution". Helpful? give kudos by clicking on the star.
Please use plain text.
Regular Contributor
devin
Posts: 51
Registered: ‎05-11-2010
My Device: 8900
My Carrier: Rogers

Re: Problems accessing data across threads

Hi Ted,

 

thanks so much for your help on this.  I looked at that article you posted and that is how I am creating my alternate entry point.  What I think is happening is that when the main method is called when the blackberry boots, up it creates the background application which seems to have its' own memory space.  Then when my main method is called again for the the UI stuff it creates another memory space.  So it seems that it is not possible to do what I want to do.  It makes sense, now that I look at it because it is a main method that is being called twice so it starts too separate apps.  I just assumed that since the code was all in the same application they would be considered one instance.

 

Is there a way to have the startup app and the UI app share the same memory space, besides using the runtime store as you suggested.

 

Thanks.

Please use plain text.
Developer
simon_hain
Posts: 15,805
Registered: ‎07-29-2008
My Device: Z10 LE
My Carrier: O2 Germany

Re: Problems accessing data across threads

runtimestore is used for exactly this purpose. i don't know of another way to share. you can communicate using global events and have some other options, but runtimestore is the easiest.

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
Regular Contributor
devin
Posts: 51
Registered: ‎05-11-2010
My Device: 8900
My Carrier: Rogers

Re: Problems accessing data across threads

Thanks to both of you.  I will just have to re-write my app to use the runtime store.

Please use plain text.
Developer
peter_strange
Posts: 19,595
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problems accessing data across threads

One other alternative, and one I prefer, is not have two separate applications.  have one application, that starts up when the device starts.  Then there is no need to share.

 

The only downside of this is that you have to careful that you do not do a System.exit().  Instead your application can go to the background when the user closes it. 

Please use plain text.
Developer
Ted_Hopp
Posts: 1,305
Registered: ‎01-21-2009
My Device: Not Specified

Re: Problems accessing data across threads

 


devin wrote:

Is there a way to have the startup app and the UI app share the same memory space, besides using the runtime store as you suggested.


 

I think that the RIM article I referenced earlier describes (fairly abstractly) how to do this. The trick is that the icon is an alternate entry point that does not have a UI. Instead, it signals the startup app to come to the foreground (and bring up its UI); the app instance started by the icon then quietly exits.

 

Like Peter noted, the startup app must not call System.exit(). That means that when it returns to the background (appearing to the user to have exited), it has merely popped the last screen from the display stack. The default action of close() is to call System.exit() if the display stack is empty; you will need to override close() to avoid that, or else organize your code so close() is never called.




Solved? click "Accept as solution". Helpful? give kudos by clicking on the star.
Please use plain text.