Alternative to multiple instances of pseudo-singleton - java

I stumbled upon a pseudo-singleton class that is responsible for housing a few collections. It looks something like this:
public class PseudoSingleton {
private List<Object> collection1;
private List<Object> collection2;
private static PseudoSingleton instance = null;
public static synchronized PseudoSingleton getInstance() {
if (instance == null) {
instance = new PseudoSingleton();
}
return instance;
}
public static synchronized void reload() {
instance = new PseudoSingleton();
}
private PseudoSingleton() {
load();
}
private void load() {
//parse some files from disk and fill collections
}
}
The reason it is coded like this is that in a few places in code a comparison of collection1 before and after reload needs to be done.
However this way seems like a major code smell to me.
I tried to refactor the code slightly by making the reload() method not static:
public synchronized void reload() {
//clear collections
//load collections
}
In order to be able to compare collection before reload I added a method that needs to be called before reloading the collection:
public List<Object> getCollection1Copy() {
return new LinkedList<>(collection1);
}
However, in review I got a comment that the previous way was better and I should leave it as is. I am not convinced. Should I insist to go my way or leave it? Or is there a better way to code it?

Related

Passing object by reference to a thread

Let's say I have a class called Object and a thread called ObjectCreator that manages the creation of an Object. For the sake of simplicity, Object has attributes: objectNumber and objectName.
If I were to create an instance of Object called instance, it would be held by ObjectCreator. Now let's say I needed another thread (let's call it ObjectChanger) to be able to see and manipulate instance; does it make sense to turn instance into a static Object?
I've managed to see results by making instance static so now I can do something like:
ObjectCreator.instance.getName();
Where getName() is a method of Object. From what I've read from answers to similar questions, static things are evil and there's always workarounds. One suggestion I've read is to pass instance to ObjectChanger as an argument for its constructor but what if instance wasn't created yet at the time I need to create an ObjectChanger?
Perhaps this question is more about OOP concepts than multi-threading or it may be a duplicate so forgive me but I'm quite lost here.
EDIT: To address frankie's and Jim's suggestions, here are some code snippets:
Object:
class Object
{
private String objectName = "Something";
private int objectNumber = 1;
public synchronized void changeNumber(int newNumber)
{
objectNumber = newNumber;
}
}
ObjectCreator:
class ObjectCreator extends Thread
{
static Object instance;
public ObjectCreator (Object something)
{
instance = something;
}
static void createObject()
{
...
}
static Object getObject()
{
return instance;
}
}
ObjectChanger:
public class ObjectChanger extends Thread
{
private Object currentInstance = null;
private int instanceNumber = null;
public void run()
{
currentInstance = ObjectCreator.getObject(); //If I were to make getObject() non-static, this line churns up an error
instanceNumber = currentInstance.getObjectNumber();
currentInstance.changeNumber(2); //valid?
}
}
If you want a thread to obtain access to an object not created within it, you must ensure that said thread has a path of references which it can follow, leading to the new object.
Consider the following code, with no threads involved.
class MyObject { /* ... */ }
interface MyObjectProvider {
MyObject getMyObject();
}
class Creator implements MyObjectProvider {
private MyObject obj;
/* ... */
#Override
public MyObject getMyObject() {
return obj;
}
/** Invoked at some point in time. */
void createMyObject() {
obj = new MyObject();
}
}
class Consumer {
private MyObjectProvider provider;
Consumer(MyObjectProvider mop) {
provider = mop;
}
void consume() {
// At some point in time...
MyObject o = provider.getMyObject();
}
}
Example of a program:
public static void main(String[] args) {
Creator creator = new Creator();
Consumer consumer = new Consumer(creator);
creator.createMyObject();
consumer.consume();
}
When you add threads to the mix, some code has to change, but the struture is the same.
The idea is to run the Creator in a thread, and the Consumer in another, as you've pointed out.
So, in short, these are the things you should be looking into:
Concurrency control: look into data races, synchronized, mutual exclusion, and their friends. Start here.
wait and notify, if the Consumer should wait for MyObject to be created. Look here.
When you have a nice grasp on these concepts, you may look into the volatile keyword (watch out for its pitfalls), and the java.util.concurrent package which provides better concurrency primitives, concurrent collections, and atomic variables.
You can put your objects in a list structure like Vector and store them in the ObjectCreator. Add a getter method to ObjectCreator which will accept an index of the object to be received.
This is just a skeleton showing the basic structure. Error handling is left as an exercise :-)
public class MyObject { ... }
...
public class MyObjectCreator {
private Map<String,MyObject> createdObjects = new HashMap<>();
public MyObject makeNewObject(int objNum, String objName)
{
MyObject o = new MyObject(objNum, objName);
this.createdObjects.put(objName,o);
}
public MyObject getObject(String objName)
{
return this.createdObjects.get(objName);
}
}
...
public class MyProgram {
public static void main(String[] args)
{
MyObjectCreator oc = new MyObjectCreator();
MyObject mo = oc.makeNewObject(10,"aNewObject");
...
MyObject o = oc.get("aNewObject");
...
If you only want to change the values of the fields of your class, you should just pass the object into your newly created thread. Then there is really no need to keep a static reference around in a holder class.
But as commented already, we need a bit more information to get to what you want to do with your object and thread.
Why cant you just make an getter in the ObjectCreator class that retrieves said Object?
ex: ObjectCreater.getMyObject()
EDIT:
I think you're looking for something like this if Im not mistaken:
public class ObjectCreator{
ArrayList<Object> children;
public ObjectCreator(){
children = new ArrayList<Object>();
}
//returns back index in children array (for accessing from other threads)
public int createObject( whatever params here ){
Object o = new Object( params );
children.add(o);
return children.size()-1;
}
}
since I dont know much about the problem you're trying to solve, Im not sure if it has to be thread safe, if you want these objects mapped, or accessed differently, but Im confused where all the confusion about static is coming...

Design issue on static initialization block

I have a design question: let me expalin in simple example:
Public class A()
{
public static HashMap map = new HashMap();
public static String url = "default";
static {
getJson();
}
//url getters and setters are defined
public static getJson() {
//code which uses url to get json and populate hashmap
}
public string getresult(String key) {
//uses hashmap to send result.
}
I am using static initialization block because i want to get json only once.
public class B {
//here I want to change url and call getJson method. If i call A.setUrl() then before setting url, A.getJson () method is called as it is in static initialization block.how can i set url first and then call getJson().
//is this a bad design?
}
Yes, it is bad design:
It is impossible to customize where A gets its data from without modifying the definition of A. Among other things, this prevents unit testing (as you probably don't want to fail the unit test if the network is unavailable ...).
If initialization fails (for instance because the remote URL is currently unavailable), you can't easily catch that exception, as you don't know which access triggered loading. You can't throw a checked exception from a static initializer. You can't retry initialization either (all subsequent access immediately result in an exception).
If you must access A through a static field, I'd recommend:
public class A {
private static Map<String, String> map;
/** must be invoked before get is first called */
public static void init(Map<String, String> newmap) {
map = newmap;
}
public static String get(String key) {
return map.get(key);
}
}
This separates the concern of using the data from the concern of obtaining it, allowing each to be replaced and tested independently.
Also consider getting rid of static, as it enforces there is only ever one map in your entire application at the same time, which is quite inflexible. (See the second code sample in Ajay's answer for how)
This should work I guess. Add a new method.
public static void getJson(String url) {
setUrl(url);
getJSon();
}
Static Initializers are generally a bad idea because unit testing becomes difficult .
Check out Misko Hevery's Guide to writing Testable Code.
You can rework the design by doing something like this :
public class A {
//Add generics
private Map map = new HashMap();
public A(Map map){
this.map = map;
}
public String getresult(String key) {
//uses hashmap to send result.
}
}
//Helper Class
public class URLToJSon() {
//Add private constructor
public static Map convertUrlToJSon(String url) {
//do the conversion and return a hashmap
}
}
In this manner we get to follow the Single Responsibility Principle.
Now both the classes are testable as well.
Where is the URL set? In the constructor? If so, simply do
//Normal init stuff like set url here, followed by
if (! some check for if json is set) {
setJson();
}

Suggestions on improving this simple object pool class for Java?

I am currently writing a game for android where there are enemies that fly across the screen and then disappear, to be replaced by other enemies. Now, this happens very fast, and my code currently performs a lot of memory allocation and deallocation to create and delete these enemy objects, so I'm trying to find a way to optimize this. I got this Pool class implementation from a book on android game dev:
public class Pool<T> {
public interface PoolObjectFactory<T> {
public T createObject();
}
private final List<T> freeObjects;
private final PoolObjectFactory<T> factory;
private int maxObjects;
public Pool(PoolObjectFactory<T> factory, int maxObjects) {
this.maxObjects = maxObjects;
this.factory = factory;
freeObjects = new ArrayList<T>(maxObjects);
}
public T newObject() {
T object = null;
if (freeObjects.isEmpty()) {
object = factory.createObject();
} else {
object = freeObjects.remove(freeObjects.size() - 1);
}
return object;
}
public void free(T object) {
if (freeObjects.size() < maxObjects) freeObjects.add(object);
}
}
Now, the way to use this class is as follows:
PoolObjectFactory<Enemy> factory = new PoolObjectFactory<Enemy>() {
public Enemy createObject() {
return new Enemy();
}
};
Pool<Enemy> enemyPool = new Pool<Enemy>(factory, 50);
The obvious problem with this method is that you can't input any parameters to the createObject() method, thus forcing you to use classes that take no arguments in their constructor. This will force me to rewrite a lot of code since the Enemy class I'm using takes several different parameters. I can think of a couple of workarounds, like this one:
PoolObjectFactory<Enemy> factory = new PoolObjectFactory<Enemy>() {
public Enemy createObject(Object... args) {
return new Enemy((Float)args[0], (Float)args[1]);
}
};
Pool<Enemy> enemyPool = new Pool<Enemy>(factory, 50);
But it's error-prone and annoying to update. I could also initialize the Enemy object in the createObject() method with bogus values and then set them manually later, or I could create a Pool class for every single object but I would really prefer not doing that.
Any suggestions on how to improve this code? How do you fellow java game developers deal with pooling objects to avoid garbage collection? Thanks very much.
1) You should override the createObject function in your PoolObjectFactory.
2) You will need a initialize() function that actually sets the parameters for each EnemyObject. Just have the constructor for the EnemyObject call the initialize function. Then, when you get the object out of the pool, you should just call initialize with your parameters and it should work perfectly.

How to defend Singleton class methods to be thread safe in Java?

I have thread safe double checked Singleton class that holds a LinkedList with get/set/size methods in the Singleton class. Then I have simple pool class that is using this Singleton class to manage pool of objects.
My question is how can I defend the methods of get/set both in the singleton and the pool class without using sync methods. Here's my code
public class SingletonDoubleCheckedLockingPattern {
private static SingletonDoubleCheckedLockingPattern s = new SingletonDoubleCheckedLockingPattern();
private LinkedList<Object> linkedList;
public int GetListObjectCount() {
return linkedList.size();
}
public Object GetObjectFromList() {
return linkedList.poll();
}
public void SetObjectFromList(Object ee) {
linkedList.add(ee);
}
private SingletonDoubleCheckedLockingPattern() {
linkedList = new LinkedList<Object>();
}
/**
* 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 SingletonDoubleCheckedLockingPattern INSTANCE = new SingletonDoubleCheckedLockingPattern();
}
public static SingletonDoubleCheckedLockingPattern getInstance() {
return SingletonHolder.INSTANCE;
}
// avoid cloning
public final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
public class SingletonObjectPool {
private int maxlistValue = 10;
public Object GetObject()
{
int listCount = SingletonDoubleCheckedLockingPattern.getInstance().GetListObjectCount();
if(listCount > 0)
{
return SingletonDoubleCheckedLockingPattern.getInstance().GetObjectFromList();
}
return null;
}
public void SetObject()
{
int listCount = SingletonDoubleCheckedLockingPattern.getInstance().GetListObjectCount();
if(listCount < maxlistValue)
{
SingletonDoubleCheckedLockingPattern.getInstance().SetObjectFromList(new Object());
}
}
}
You could use a BlockingQueue which is thread safe. You shouldn't need to check whether a collection is empty before attempting to remove an element, the collection has a method to do this.
To simplify your code and make it thread safe you can do.
public class SingletonObjectPool {
private static final int maxlistValue = 10;
private static final BlockingQueue queue
= new ArrayBlockingQueue(maxListValue);
public static Object getObject() {
return queue.poll();
}
public static void addObjectAsRequired() {
queue.offer(new Object());
}
}
The only way I can think that you can possibly call methods such as GetListObjectCount without using synchronized, is if the list itself is thread-safe and will behave sensibly when this method is called in the face of concurrent modifications.
In that case, there won't be any other problems, as the reference to the list itself never changes. You may want to declare it as final to make this abundantly clear, and to have the compiler warn anyone who tries to reassign the list. (If this were a requirement, the reference would need to be volatile at the very least, but it opens up lots of other questions in the correctness of multiple operations of your class).
The bottom line is that "thread safety" is not a simple, binary concept. You can't just say a particular class and/or method is thread-safe; rather, it's about what combinations of methods you can call with useful and correct semantics.

Pattern for lazy thread-safe singleton instantiation in java

the lazy thread-safe singleton instantion is kinda not easy to understand to every coder, so i wanted to create a class in our enterprise framework that would do the job.
What do you think about it? Do you see something bad about it? Is there something similar like in Apache Commons? How can i make it better?
Supplier.java
public interface Supplier<T> {
public T get();
}
LazyThreadSafeInstantiator.java
public class LazyThreadSafeInstantiator<T> implements Supplier<T> {
private final Supplier<T> instanceSupplier;
private volatile T obj;
public LazyThreadSafeInstantiator(Supplier<T> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
#Override
// http://en.wikipedia.org/wiki/Double-checked_locking
public T get() {
T result = obj; // Wikipedia: Note the usage of the local variable result which seems unnecessary. For some versions of the Java VM, it will make the code 25% faster and for others, it won't hurt.
if (result == null) {
synchronized(this) {
result = obj;
if (result == null) {
result = instanceSupplier.get();
obj = result;
}
}
}
return result;
}
}
Example usage:
public class Singleton1 {
private static final Supplier<Singleton1> instanceHolder =
new LazyThreadSafeInstantiator<Singleton1>(new Supplier<Singleton1>() {
#Override
public Singleton1 get() {
return new Singleton1();
}
});
public Singleton1 instance() {
return instanceHolder.get();
}
private Singleton1() {
System.out.println("Singleton1 instantiated");
}
}
Thanks
the lazy thread-safe singleton
instantion is kinda not easy to
understand to every coder
No, it's actually very, very easy:
public class Singleton{
private final static Singleton instance = new Singleton();
private Singleton(){ ... }
public static Singleton getInstance(){ return instance; }
}
Better yet, make it an enum:
public enum Singleton{
INSTANCE;
private Singleton(){ ... }
}
It's threadsafe, and it's lazy (initialization happens at class loading time, and Java does not load classes until they are are first referred).
Fact is, 99% of the time you don't need lazy loading at all. And out of the remaining 1%, in 0.9% the above is perfectly lazy enough.
Have you run a profiler and determined that your app belings to the 0.01% that really needs lazy-loading-at-first-access? Didn't think so. Then why are you wasting your time concocting these Rube Goldbergesque code abominations to solve a non-existing problem?
For a version that is more readable (in my opinion) than the one presented in the question, one can refer to the Initialization on Demand Holder idiom, introduced by Bill Pugh. Not only is it thread-safe considering the Java 5 memory model, the singleton is also lazily initialized.
Looks overengineered to me.
I really don't see how having helper class helps.
First of all, it's using double-locking idiom, and it has been proved once and again broken.
Second, if you HAVE TO use singleton, why not initialize static final instance.
public class Singleton1 {
private static final Singleton1 instanceHolder =
new Singletong1( );
public Singleton1 instance() {
return instanceHolder;
}
private Singleton1() {
System.out.println("Singleton1 instantiated");
}
}
This code is thread-safe and has been proven to work.
Check Vineet Reynolds' answer for when you need to initialize singleton instance on a first get. In many cases I think that approach is an overkill as well.
Isn't the double checked locking pattern and use of volatile broken on JIT compilers and multi-core/processor systems due to the Java Memory Model & possibility of out of order execution?
More generally, it seems that a framework for singletons is overkill for what is essentially a pretty straightforward pattern to implement correctly.
I would agree with other posters and say that this does seem like overkill, but have said that i do think that this is something that a junior developer is likely to get wrong. I think that because the behaviour of the supplier that constructs the singleton (shown below) is going to be the same in nearly all cases, i would be tempted to put this as default behaviour in the LazyThreadSafeInstantiator. The use of the annonomous inner class every time you want to use a singleton is really messy.
#Override
public Singleton1 get() {
return new Singleton1();
}
This could be done by providing an overloaded constructor that takes the Class to the singleton required.
public class LazyThreadSafeInstantiator<T> implements Supplier<T> {
private final Supplier<T> instanceSupplier;
private Class<T> toConstruct;
private volatile T obj;
public LazyThreadSafeInstantiator(Supplier<T> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
public LazyThreadSafeInstantiator(Class<t> toConstruct) {
this.toConstruct = toConstruct;
}
#Override
// http://en.wikipedia.org/wiki/Double-checked_locking
public T get() {
T result = obj; // Wikipedia: Note the usage of the local variable result which seems unnecessary. For some versions of the Java VM, it will make the code 25% faster and for others, it won't hurt.
if (result == null) {
synchronized(this) {
result = obj;
if (result == null) {
if (instanceSupplier == null) {
try {
Constructor[] c = toConstruct.getDeclaredConstructors();
c[0].setAccessible(true);
result = c[0].newInstance(new Object[] {});
} catch (Exception e) {
//handle
}
result =
} else {
result = instanceSupplier.get();
}
obj = result;
}
}
}
return result;
}
}
This would then be used like so.
private static final Supplier<Singleton1> instanceHolder =
new LazyThreadSafeInstantiator<Singleton1>(Singleton1.getClass());
This is my opinion is a bit cleaner. You could alos extend this further to use constructor arguments.
Lazy<X> lazyX= new Lazy<X>(){
protected X create(){
return new X();
}};
X x = lazyX.get();
abstract public class Lazy<T>
{
abstract protected T create();
static class FinalRef<S>
{
final S value;
FinalRef(S value){ this.value =value; }
}
FinalRef<T> ref = null;
public T get()
{
FinalRef<T> result = ref;
if(result==null)
{
synchronized(this)
{
if(ref==null)
ref = new FinalRef<T>( create() );
result = ref;
}
}
return result.value;
}
}
except maybe the first get() in a thread, all get() calls require no synchronization or volatile read. the original goal of double checked locking is achieved.

Categories

Resources