4

I have an application in java that uses two different threads.And for sharing data between these two threads I wanna use a Singleton class.

The data that needs to be shared between threads is (Latitude,Longitude).

And here is my problem:What should I use for storing this data in the Singleton class?

Some Lists..?

And if you can also provide an example it would be fantastic.Thank you!

Is this Singleton ????How could I make it non-Singleton

EDIT:

I have a java app that does the following thing:

1.The first thread(which is a ThreadPool)-which I believe will also write in the BlockingQ Listens to one port for incoming connections from five different users Let's call them :

user1 user2 user3 user4 user5

each of them sending GPS data.

2.The second thread-which will read from the BlockingQ. In the same time my java app listens to a second port where waits for another client(different from those who send GPS data) to connect to it.

Now...I have a second app that connects to the java app that I've just described it.

In this second app I have a list user1...user5 and depinding on which item I will choose(user1...5) I have to receive the correct data from there.

So now....how do I write/read the data in the BlockingQ in order for me to receive the correct data???

j0k
  • 22,600
  • 28
  • 79
  • 90
embry
  • 309
  • 6
  • 18
  • Is your data going to change during the program execution ? If yes synchronized method is recommended. – VirtualTroll May 19 '11 at 13:56
  • A thread writes data to the class and another one reads rhe data from there.But also want to store that data because,yes it changes.I need to store it and when the reading thread is available he could read it! – embry May 19 '11 at 13:59
  • @embry: first you need to build a thread-safe singleton (http://www.jguru.com/faq/view.jsp?EID=124425) to avoid having two singletons afterwards you should use a similar approach when getting and setting the values from the singleton ... lock the object containing the values – VirtualTroll May 19 '11 at 14:05
  • I did that;)...now what's next? – embry May 19 '11 at 14:15
  • @Amine - ..or he could just save himself all that greif and not make it a singleton. – T.E.D. May 19 '11 at 14:17
  • What to use instead of a singleton?I don't want to use DB and store the data in tabels! – embry May 19 '11 at 14:23
  • @embry - How about a normal class? – T.E.D. May 19 '11 at 14:27
  • fantastic....I agree.U convinced me that singleton will bring me grief,pain and sorrow.I've edited my question.But hear me out...I need to use this class for multiple workers(multithreading will write) to write in it and only one thread will read from it at a time.How to do that.Thx:) – embry May 19 '11 at 14:32

4 Answers4

4

I think what you are trying to achieve is a Producer Consumer Pattern. You should use a BlockingQueue and an immutable Coordinate object with Latitude and Longitude for that.

Coordinate should only have the two fields Longitude and Latitude that are both final fields and can only be set with the constructor. This way you can make sure, that you don't have any race conditions or change the fields by accident with the wrong thread.

BlockingQueue does not store the data permanently, so only if you need to do that you could create a Singleton.
The better solution would be to create a class like ShareData and just pass them to the two threads so you can save yourself some time creating a threadsafe Singleton. This could look like this:

public interface ShareData {
    public void AddToList(Coordinate coord); // add to BlockingQueue and an internal store here
    public Coordinate TakeFromList();  // take from BlockingQueue
}

The Coordinate class should look like this and is threadsafe, since it is immutable and cannot change its value.

public class Coordinate {
  private final double lon;
  private final double lat;

  public Coordinate(double lon, double lat) {
    this.lon = lon;
    this.lat = lat;
  }

  public double getLon() {
    return lon;
  }

  public double getLat() {
    return lat;
  }
}
Simon Woker
  • 4,994
  • 1
  • 27
  • 41
  • Well,I'm not to advanced but I have such a class....what does actually means to be singleton.I'll edit my question with the code. – embry May 19 '11 at 14:28
  • Take a look at the example at the top here: http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html. Basically this example shows you an application with 1 thread that is producing objects and 2 threads that are consuming the produced objects. You should be able to adapt this simple example to your program by adding a Coordinate class (I edit my answer) – Simon Woker May 19 '11 at 14:36
  • 2
    The basic approach is correct, but you don't use a SINGLETON for that. You use an ordinary object and give it as parameter to the two threads when you start them. (So you can have many pairs of threads using your class) – Angel O'Sphere May 19 '11 at 15:13
  • don't use a singleton, instead use a `BlockingQueue`! That's what we want to tell you :) – Simon Woker May 19 '11 at 15:18
  • @Simon But u just said that my BlockingQueue won't store the data permanently!:"BlockingQueue does not store the data permanently, so only if you need to do that you should create a Singleton which could look something like this:..." – embry May 19 '11 at 15:24
  • Yeah, but directly beneath that: "The better solution would be to create a class like ShareDataSingleton and **don't make it a Singleton**, but instead just pass them to the two threads so you can save yourself some time creating a threadsafe Singleton." Sorry for being a little unclear there. – Simon Woker May 19 '11 at 15:26
  • I have another question:Can this Blocking queue be used with ThreadPool? – embry May 19 '11 at 16:11
  • sure, why not? AFAIK you only pass `Runnables` to the ThreadPool. So if you pass the Runnable the `BlockingQueue` first and then add it to the Pool, there's no problem – Simon Woker May 19 '11 at 16:18
  • Yes, all use the same. That's the point of using the BlockingQueue. You could also use different Queues if you want to, I don't know what you want to do in the end so I cannot tell you what's the best idea there. For the differentiation: You could modify the `Coordinate` object above and add a `int workerID` or whatever to it. – Simon Woker May 19 '11 at 16:57
  • That's a completely different question where the BlockingQueue doesn't make any sense anymore... :/ – Simon Woker May 19 '11 at 17:29
  • I would be gratefull if u would help me with this one:).Thx – embry May 19 '11 at 17:45
2

My advice would be to not bother with the singleton. Singletons are almost never a good idea. If you don't want more than one of them, just don't make more than one of them. If you want it global, declare your one object of the class global (but better yet, just pick a class to own it.).

I don't know your program, but I'd lay pretty good odds that you will never see a bug caused by somebody inadvertantly making more than one of your shared data class objects. However, getting thread-safe singletons coded right is a very sticky problem, and you are very likely to have bugs if you try to do that.

And then what happens one day when you discover that you need another pair of those communicating threads for some reason? You'd want another one of those shared data objects to go with them of course, but because you made it a singleton it becomes a major rewrite of that class rather than a triviality.

Community
  • 1
  • 1
T.E.D.
  • 44,016
  • 10
  • 73
  • 134
0

Just make a class to store that information. lat/lon can be represented by doubles.

public class OuterClass {
    public static synchronized InnerSingleton getSingleton() {
        if(singleton == null) {
            singleton = new InnerSingleton();
        }
        return singleton;
    }

    private InnerSingleton singleton;

    class InnerSingleton {
        private double lat, lon;
        private InnerSingleton() { }
        public double getLatitude() { return lat; }
        public double getLongitude() { return lon; }
        public void setLatitude(double l) { lat = l; } //maybe validate? -90 <= lat <= 90
        public void setLongitude(double l) { lon = l; } //maybe validate? -180 <= lon <= 180
   }

}
ds_student
  • 86
  • 2
  • Yes,I thought about this.But once new information comes in the old one is lost.And my question is what to use to store (lat,lon) in order not to loose it?A buffer maybe? – embry May 19 '11 at 14:05
  • it's not thread safe in the slightest, non volatile members will result in some writes not coming through... and more – ratchet freak May 19 '11 at 14:07
  • I know this is just a toy example, but as presented this combines my two biggest pet peeves into one: Singletons (and a unsafe one for the given purpose at that) with a class that is otherwise nothing but bare setters and getters for private members. This class is basically a C `struct` with a horrible Napolean complex. – T.E.D. May 19 '11 at 14:33
0

I'd advise a concurrent queue

look in java.util.concurrent for several implementations that could help you: ConcurrentLinkedQueue, ConcurrentBlockingQueue

so you have a singleton queue that one thread reads from and the other writes to

ratchet freak
  • 47,288
  • 5
  • 68
  • 106