So I had a question on here the other day about how to accessing the same data class with two different other classes without creating separate instances. It was recommended to use a singleton so i have done some research but there isn't a lot about it.
The issue I'm having is that my main class gets a null pointer exception when trying to access the data singleton. But my other class can access it and get the data just fine. How exactly is that possible? I have a pretty basic setup...
singleton
public enum laneData {
INSTANCE;
private String laneID;
public String getLaneID() {
return laneID;
}
public void setLaneID(String laneID) {
this.laneID = laneID;
}
}
main class call
private laneData laneData;
public void init() {
laneData.setLaneID("test"); //these two lines each throw null pointer unless commented out
System.out.println(laneData.getLaneID());
....
other class
public class XMLParser {
private LaneGUI laneGUI;
private laneData laneData;
public void parseInputString(String input){
laneData.setLaneID(getCharacterDataFromElement(line)); //both of these work fine
System.out.println("stored ID: " + laneData.getLaneID());
You need private laneData laneData = laneData.INSTANCE;.
You can also just use laneData.INSTANCE.getLaneID().
Java guidelines also recommend than Class and Enum names be capitalized, I.E. LaneData.
It was recommended to use a singleton
so i have done some research but there
isn't a lot about it.
There is a lot out there about the singleton pattern.
This is an example singleton (note the differences)
public class MySingleton {
private String label;
private static MySingleton single;
private MySingleton(String label) {
this.label = label;
}
public static MySingleton getInstance(String label) {
if (singleton == null) singleton = new MySingleton(label);
return singleton;
}
}
Related
I have written a storm topology, and set its workers number to 1.
So, I think all of its components should be run in the same process. And I want to share a common object between multiple components in the topology, so I use singleton pattern:
1, I initialize the singleton object when the unique spout has been opened.
2, Then, I use the singleton object in other components by calling the function getInstance().
But, I found that I will get the different objects between different components.
Thanks for your replies. The key code of the problem are listed as follows:
The singleton class code:
public class TraceApplicationContext {
private volatile static TraceApplicationContext instance = new TraceApplicationContext();
private TraceApplicationContext() {
}
public static TraceApplicationContext getInstance() {
return instance;
}
}
The SpoutA class code:
public class SpoutA extends BaseRichSpout {
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
TraceApplicationContext.getInstance().init();
}
}
The BoltA code:
public class BoltA extends BaseRichBolt {
private static JedisCluster jedisCluster = TraceApplicationContext.getInstance().getJedisCluster();
}
The BoltB code:
public class BoltB extends BaseRichBolt {
private static JedisCluster jedisCluster = TraceApplicationContext.getInstance().getJedisCluster();
}
After initialized the TraceApplicationContext singleton object in SpoutA, I check the object return by TraceApplicationContext.getInstance().getJedisCluster(), it's not null. But I check it in BoltA and BoltB, the object returned by TraceApplicationContext.getInstance().getJedisCluster() is null.
Have anyone met the same problem or know what's wrong with such problem?
Please help!
Thank you!
If you can't use enum as #Jorge_B says you can use a synchronized block in the getInstance() method
public class MySingleton {
private static volatile MySingleton instance;
private MySingleton() { ... }
public static MySingleton getInstance() {
if (instance == null) {
synchronized(MySingleton.class) {
if (instance == null) {
instance = new MySingleton();
}
}
}
return instance;
}
}
http://en.wikipedia.org/wiki/Singleton_pattern
EDIT
But it's may be not a singleton problem
The fact that the getJedisCluster() return different values doesn't mean that it's not the same singleton but rather that the state of the singleton has changed
try to make the jedisCluster final inside the singleton (a final property couldn't be changed but must be initialized inside the constructor)
private final JedisCluster jedisCluster;
if you can't try to track when the jedisCluster is changed : use of setter...
If you have made sure all your processes run in the same JVM, try to implement your Singleton as an Enumeration of a single element. This should solve every possible concurrence problem with the object initialization.
For example:
An implementation like
public class MySingleton {
private static MySingleton instance;
private MySingleton() { ... }
public static MySingleton getInstance() {
if (instance == null) { instance = new MySingleton() }
return instance;
}
}
Is prone to concurrency problems. However, one like this
public enum MySingleton {
INSTANCE;
private MySingleton() {...}
}
Should work everywhere.
As with my experience, I was using singleton cassandra session object, as well as singleton for application properties in my storm topology.
Since these singleton objects do not have any varying state , even when we have multiple WorkerProcess(WP) (ie one JVM per WP), each WP will have a copy of the singleton and can be made use without issue.
As far as best practice is concerned, its better to set the static singletons to the config object while submitting the topology, and the prepare method will supply it to individual tasks.
https://groups.google.com/forum/#!topic/storm-user/rWeQpGEnT9Q
I have a monitor class with a static (and optionally final) variable called ClockValues. This variable is used by every other static method. However, the ClockValues object comes from an external source. Is there way I can ensure external objects and threads to initialize ClockValues before using any static methods in this class?
Kind of like a constructor but for static variables.
public class SharedData {
private static final MutexSem mutex = new MutexSem();
private static ClockValues clock;
//my static "Constructor"
//but I can't force other objects to call this method before all other methods in this class
//I understand I could use a flag to signal initilization, but I was looking for a cleaner way
public static void initialize(ClockValues c){
mutex.take();
clock= c;
mutex.give();
}
public static void doSomething(){
mutex.take();
//do something with `clock`
mutex.give();
}
//... more methods using `clock` variable
}
I don't think you can do what you want with static methods. You could probably do something with a singleton pattern:
public class SharedData {
private static final MutexSem mutex = new MutexSem();
private static SharedData instance;
private ClockValues clock;
public static SharedData getInstance(ClockValues c) {
mutex.take();
if (instance == null) {
instance = new SharedData(c);
}
mutex.give();
return instance;
}
private SharedData(ClockValues c) {
clock = c;
}
public void doSomething() { // NOTE: no longer static
mutex.take();
//do something with `clock`
mutex.give();
}
//...
}
Unfortunately, that would require every call to getInstance to have a ClockValues value to pass as an argument. Depending on your architecture, though, this might be a feasible alternative.
the standard pattern to initialize singletons is described in Effective Java, Second Edition, Item 71:
public class AService {
private static int init = 0;
private static class Holder {
private static final AService theService = new AService(init);
}
private AService(int init) {
System.out.println("AService instance initialized with " + init);
}
public static AService instance(int init) {
AService.init = init;
return Holder.theService;
}
}
Thus instantiation of the service singleton is delayed until first call to instance (which may took additional arguments etc) and you may perform a more complex instantiation. Depending on your project initialization logic you may split .instance(init) into .getFirstInstance(init) and .instance(), but this is solely up to you.
I have come across another article in stackexchange on various ways to implement java singleton. One of the ways shown is the following example. It has been voted very low. Wanted to understand why.
What is an efficient way to implement a singleton pattern in Java?
public class Singleton {
private static Singleton instance = null;
static {
instance = new Singleton();
// do some of your instantiation stuff here
}
private Singleton() {
if(instance!=null) {
throw new ErrorYouWant("Singleton double-instantiation, should never happen!");
}
}
public static getSingleton() {
return instance;
}
}
As #Craig says in the comments:
Not true. static variables are initialized along with static blocks when the class is loaded. No need to split the declaration.
Essentially it was down voted because it was misinformation, a lot of what he was saying was just plain not true. Specifically, initializing a static variable with a static method will occur when the class is loaded, while the author claimed that this was not the case.
His argument also doesn't really make sense, "data insertion" could just be done within the constructor.
With that said, the above code will work fine, it's just an odd way of doing it, and arguably the least stylistic.
following solution make sure it's thread safe
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() { }
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
public static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
This is not a good way to implement it.
As static variables are initialized at JVM load time, just make the singleton final:
public final class Singleton
{
private static final Singleton INSTANCE = new Singleton();
private Singleton()
{
// build it
}
public static Singleton getInstance()
{
return INSTANCE;
}
}
I have been having a hard time understanding how to use a singleton to share a common variable. I am trying to make a blackberry app which has two entry points which need to share a common variable, iconCount. I have been advised to use a singleton with the RunTimeStore API by someone on a forum. Googling around eventually leads to:
http://docs.blackberry.com/en/developers/deliverables/17952/CS_creating_a_singleton_by_using_rutnime_store_1554335_11.jsp
I have been a few pages deep in Google but I still can`t understand what this does and how to implement it. My current understanding is that a singleton will create a "global variable" somehow through the code:
class MySingleton {
private static MySingleton _instance;
private static final long GUID = 0xab4dd61c5d004c18L;
// constructor
MySingleton() {}
public static MySingleton getInstance() {
if (_instance == null) {
_instance = (MySingleton)RuntimeStore.getRuntimeStore().get(GUID);
if (_instance == null) {
MySingleton singleton = new MySingleton();
RuntimeStore.getRuntimeStore().put(GUID, singleton);
_instance = singleton;
}
}
return _instance;
}
}
And another question would be how would I create a variable from this singleton? I need to declare variable iconCount = 0 at the beginning and then be able to use it. Would declaring it be something like
Integer iconCount = (Integer) RuntimeStore.getInstance();
? This is very new to me as I have just started Java so if anyone could explain this keeping in mind you're communicating with a novice I would be very grateful. Thanks in advance!
You would call
MySingleton.getInstance()
to get the instance in your app. The point is that getInstance is controlling access to the underlying object.
Also, you should make your constructor private, so it's only accessible in that file.
To define a property on you singleton class, just declare a non-static property. Each instance of the class will have its own copy, but you are controlling the creation of the objects, so their should only ever be 1 (per JVM). So
class MySingleton {
private static MySingleton _instance;
private static final long GUID = 0xab4dd61c5d004c18L;
private Integer iconCount; // non-static method, add a public getIconCount below
...
}
and then you can access it via
MySingleton.getInstance().getIconCount();
They mean please make sure that user initializing MySingleton class just onetime so you will not have problem with multiple instances and initialize two count in the same time. I mean from multiple instance something like below:
Mysingleton single = new Mysingleton();
Mysingleton single2 = new Mysingleton();
Because both initilaization can have diffetent count. You need something like this:
public class IconManager {
private static iconManager _instance;
private static final long GUID = 0xab4dd61c5d004c18L;
private static int count = 0;
// constructor
IconManager() {
}
public static IconManager getInstance() {
if (_instance == null) {
_instance = (IconManager) RuntimeStore.getRuntimeStore().get(GUID);
if (_instance == null) {
IconManager singleton = new IconManager();
RuntimeStore.getRuntimeStore().put(GUID, singleton);
_instance = singleton;
}
}
return _instance;
}
public static int getCount() {
return count;
}
public static void setCount(int count) {
this.count = count;
}
}
and after you can create an instance for the class:
public static void main(String[] args){
IconManager iconManager = IconManager.getInstance();
iconManager.setCount(iconmanager.getCount() + 1);
}
So application will do first validation, if there is already an instance it will update existing one, if not than it will create new one.
You can't cast your MySingleton class to Integer.
And in your example you don't use your singleton but RuntimeStore !
You can use an integer field of your class Singleton, initalized to 0 in the constructor of your singleton (private constructor) and get it by doing :
MySingleton.getInstance().getIntegerField()
here is a detailled description of the singleton pattern :
http://en.wikipedia.org/wiki/Singleton_pattern
I think you misunderstand the use of the singleton. the singleton is not injected in your RuntimeStore, it is a classic java object. The only subtile think to know about a singleton is that its constructor is private and the class MySingleton can have only one instance which is always returned when your singleton.getInstance() is called
In my work I stumbled upon such a design issue:
I need one instance of a Manager class per thread
These instances should be globally accessible, like in the singleton pattern via a static function
Each thread might need to initialize its instance with different arguments
The lifetime of these instances should be controllable, sometimes it would be beneficiary to remove an instance and allow GC to collect it
The first two points would make it a 'per thread singleton' if such a thing exists.
This is what I came up with (the code is simplified, I've omitted safety checks and so on):
public class Manager {
private final static ThreadLocal<Manager> local = new ThreadLocal<Manager>();
private int x;
Manager(int argument) { x = argument; }
public static void start(int argument) { local.set(new Manager(argument); }
public static void clean() { local.remove(); }
private void doSomething1() { x++; .... }
private int doSomething2() { if (--x == 0) clean(); ... }
public static void function1() { local.get().doSomething1(); }
public static int function2() { return local.get().doSomething2(); }
}
As you can see the clean function can be also called from within the private methods.
Also notice that through the use of static functions the reference to the instance is never leaked, so instances assigned to different threads won't get mixed.
This works quite ok, but then I got another requirement:
Different threads may need to utilize different implementations of Manager class
So I defined an interface:
public interface ManagerHandler {
void method1();
int method2();
}
And modified the Manager class:
public class Manager {
private final static ThreadLocal<ManagerHandler> local = new ThreadLocal<ManagerHandler>();
public static void start(int argument) {
ManagerHandler handler;
// depending on the context initialize handler to whatever class it is necessary
local.set(handler);
}
public static void clean() { local.remove(); }
public static void function1() { local.get().method1(); }
public static int function2() { return local.get().method2(); }
}
An example implementation would look like this:
public class ExampleManagerImplementation implements ManagerHandler {
private int x;
public ExampleManagerImplementation(int argument) { x = argument; }
public void method1() { x++; .... }
public int method2() { if (--x == 0) Manager.clean(); ... }
}
Manager class works here as a facade, forwarding all the calls to the appropriate handler. There is one big issue with this approach: I need to define all the functions both in the Manager class and in the ManagerHandler interface. Unfurtunately Manager class can't implement ManagerHandler interface, because it has static functions rather than methods.
The question is: can you think of a better/easier way to accomplish all the goals I've listed above that would be free of this issue?
There is not much you can do, as you basically need to proxy interface methods through static methods. I could only think of two ways to achieve the same functionality differently:
If you're using a DI framework, you can get rid of the static Manager and use an injected implementation of ManagerHandler which will contain the ThreadLocal.
Generate (as in 'bytecode generation') the static ManagerAccess class using the methods found in the ManagerHandler interface.
Personally, I wouldn't think of having the static ManagerAccess class (which contains the ThreadLocal) around as a serious design issue. At least as long as it keeps to its own set of responsibilities (accessing thread-scoped instances and proxying calls) and doesn't venture anywhere else.
If you're going with this design, is it necessary for Manager to totally hide ManagerHandler interface, or could you expose it so you don't have to delegate every method?
class Manager {
public static ManagerHandler getHandler() { return local.get(); }
}
The trick for creating a singleton per thread class is to use ThreadStatic attribute on your private static _current field which makes it scoped by thread. In this way, the _current field will be stored inside thread memory which is not accessible for the other threads and not shared memory of AppDomain. So, it will be available only in the scope of the thread. On the other hand, the Current property is accessible across all threads in that AppDomain but when it is called it will return the correct instance for that thread. Here is the code that you need:
public sealed class Manager
{
// As you are using the ThreadStatic here you cannot
// call the static constructor or use the Lazy implimentation for
// thread-safty and you have to use the old fashin Lock and anti-pattern.
private static readonly object _criticalArea = new object();
[ThreadStatic]
private static Manager _current;
public static Manager Current
{
get
{
if (_current == null)
{
lock (_criticalArea)
{
if (_current == null)
{
_current = new Manager();
}
}
}
return _current;
}
}
private Manager()
{
}
public string WhatThreadIsThis { get; set; }
}
[TestClass]
public class SingeltonPerThreadTest
{
private readonly EventWaitHandle _threadHandler = new EventWaitHandle(false, EventResetMode.AutoReset);
private string _sharedMemory = "I am the shared memory and yet in main thread :(";
[TestMethod]
public void TestSingeltonPerThread()
{
// Creates a _current for main thread.
Manager.Current.WhatThreadIsThis = "I am the main thread :)";
// Start another thread.
(new Thread(CallTheThreadBaseSingelton)).Start();
// Wait for it to be finished.
_threadHandler.WaitOne();
Assert.AreEqual("I am the main thread :)", Manager.Current.WhatThreadIsThis, "I am not the main thread :( ");
Assert.AreEqual("I am the other thread ;)", _sharedMemory, _sharedMemory);
}
private void CallTheThreadBaseSingelton()
{
// Creates a _current for this thread (this thread is the other one :)) ).
Manager.Current.WhatThreadIsThis = "I am the other thread ;)";
_sharedMemory = Manager.Current.WhatThreadIsThis;
_threadHandler.Set();
}
}
Cheers.