I'm developing computer vision application and I will need Classifier class. This class will be immutable per run of application and it loads the trained data from disk on initialization. I want to ensure that whole program will have access to same trained data and I want to block reloading the from disk once they are loaded.
What I was considering was to use either static class or singleton. I'm not sure how to load data to static class, because the path to data file is not know at compile time - it will be program argument. So I was thinking of Singleton pattern, but there I don't know how to initialize it dynamically.
My idea was to use following:
class Singleton {
private static Singleton instance;
private Singleton() { ... }
private static SomeDataObject data;
public static Singleton getInstance() {
if(instance == null)
instance = new Singleton();
return instance;
}
public static init(string dataPath){
if(data == null)
loadDataFromFile(dataPath)
}
}
This would not work, because I have no control which method will be called first.
I know the proper way would be to create the instance with data at the begining and pass it to all classes and methods which need it, but that's not really general solution. I can keep track of all calls to Classifier in my own code, but if I would make the code as API, this would be a problem.
In short how to initialize singleton at runtime?
I don't think (exactly) what you want to do would work.
The below would work:
public static void main(String[] args)
{
Singleton.init("somepath");
...
Singleton.getInstance().doingStuff();
...
}
A better implementation may be: (which would cause a NullPointerException if you try to use it without calling init first) (not really Singleton any more though)
private static Singleton instance;
private SomeDataObject data;
private Singleton(String path) { loadDataFromFile(path); ... }
public static Singleton getInstance() {
return instance;
}
public static void init(String dataPath){
instance = new Singleton(dataPath);
}
Then there's: (possible bad coding practice aside)
class Main
{
public static void main(String[] args)
{
Singleton.currentPath = "somepath";
...
}
}
class Singleton
{
public static String currentPath = null;
private static Singleton instance;
private SomeDataObject data;
private Singleton(String path) { loadDataFromFile(path); ... }
public static Singleton getInstance() {
if(instance == null && currentPath != null)
instance = new Singleton(currentPath);
return instance;
}
}
which I suppose doesn't really solve much.
I use something that is "more" threadsafe than the current winning solution with almost no synchronized used.
import java.util.function.Supplier;
public class InitOnce {
/**
* Marked as final to prevent JIT reordering
*/
private final Supplier<String> theArgs;
private InitOnce(Supplier<String> supplier) {
super();
this.theArgs = supplier;
}
/**
* Uses the arguments to do something
*
* #return
*/
public String doSomething() {
return "Something : " + theArgs.get();
}
/**
* Initializes all the things
*
* #param someArgs
*/
public static synchronized void init(final Supplier<String> someArgs) {
class InitOnceFactory implements Supplier<InitOnce> {
private final InitOnce initOnceInstance = new InitOnce(someArgs);
#Override
public InitOnce get() {
return initOnceInstance;
}
}
if (!InitOnceFactory.class.isInstance(instance)) {
instance = new InitOnceFactory();
} else {
throw new IllegalStateException("Already Initialized");
}
}
private static Supplier<InitOnce> instance = new InitOnceHolder();
/**
* Temp Placeholder supplier
*
*/
private static final class InitOnceHolder implements Supplier<InitOnce> {
#Override
public synchronized InitOnce get() {
if (InitOnceHolder.class.isInstance(instance))
throw new IllegalStateException("Not Initialized");
return instance.get();
}
}
/**
* Returns the instance
*
* #return
*/
public static final InitOnce getInstance() {
return instance.get();
}
}
Related
in my project i am trying to use singleton class to store data in it. When im trying to access it from Service class, its creating new instance instead of using previous Singleton instance. I read a lot of post on github and couldn't find working answer
My Singleton class
import android.util.Log;
import com.softelnet.ksavi.android.model.AttachmentRequest;
import java.util.LinkedList;
public class AttachmentsUpdateQueue {
private static class Holder {
private static final AttachmentsUpdateQueue singleInstance = new AttachmentsUpdateQueue();
}
private AttachmentsUpdateQueue() {
Log.d("pox", "new instance");
}
private LinkedList<AttachmentRequest> attachmentsQueue = new LinkedList<>();
public static AttachmentsUpdateQueue getInstance() {
return Holder.singleInstance;
}
public AttachmentRequest getAttachmentForUpload() {
Log.d("pox", "get, size:" + attachmentsQueue.size());
if (attachmentsQueue.size() > 0) {
return attachmentsQueue.get(0);
} else {
return null;
}
}
public int getSize() {
return attachmentsQueue.size();
}
public void addAttachmentForUpload(AttachmentRequest attachment) {
attachmentsQueue.addLast(attachment);
Log.d("pox", "added, size:" + attachmentsQueue.size());
}
}
Adding data to Singleton
AttachmentsUpdateQueue.getInstance().addAttachmentForUpload(new AttachmentRequest(oprCtx.getUser(),task.getId(),attachment,isAttribute));
Getting data from Singleton
AttachmentRequest req = AttachmentsUpdateQueue.getInstance().getAttachmentForUpload();
may be you can write like this, which is named DCL(double check lock).
private volatile static AttachmentsUpdateQueue instance = null;
private AttachmentsUpdateQueue(){
System.out.println("Single: " + System.nanoTime());
}
public static AttachmentsUpdateQueue getInstance(){
if(instance == null){
synchronized (AttachmentsUpdateQueue.class) {
if(instance == null){
singleInstance = new AttachmentsUpdateQueue();
}
}
}
return instance;
}
I'm trying to read the something from a context class and always got null. As I debuged it I found out that for some reason there isn't anything written in my context class.
Code where context gets written:
for (Mitarbeiter m : mitarbeiterList){
if (m.getName().equals(nameSuche)){
maController = m;
logger.info(m);
ContextMAAbrechnung.getInstance().setMitarbeiter(m);
}
}
Code of context class:
package slgp.gastrosoftware.gui.controller;
import slgp.gastrosoftware.model.Mitarbeiter;
public class ContextMAAbrechnung {
private static final ContextMAAbrechnung INSTANCE = new ContextMAAbrechnung();
private Mitarbeiter mitarbeiter;
private ContextMAAbrechnung() {}
public Mitarbeiter getMitarbeiter() {
return mitarbeiter;
}
public void setMitarbeiter(Mitarbeiter mitarbeiter) {
this.mitarbeiter = mitarbeiter;
}
public static ContextMAAbrechnung getInstance() {
return INSTANCE;
}
}
When setMitarbeiter is called it is not null: https://snag.gy/JKeFk7.jpg
As I get to the this.mitarbeiter = mitarbeiter part one is null and the other isn't. https://snag.gy/BAuFey.jpg
What did I do wrong?
There wasn't any mistake there, I didn't check it properly while I was debuging.
I have written a Thread Pool and I am not able to write the Junits(PowerMock) for that class.
public enum ThreadPool {
INSTANCE;
private static final String THREAD_POOL_SIZE = "threadpool.objectlevel.size";
private static TPropertyReader PROP_READER = new PropertyReader();
private final ExecutorService executorService;
private static final ILogger LOGGER = LoggerFactory
.getLogger(ReportExecutorObjectLevelThreadPool.class.getName());
ThreadPool() {
loadProperties();
int no_of_threads = getThreadPoolSize();
executorService = Executors.newFixedThreadPool(no_of_threads);
}
public void submitTask(Runnable task) {
executorService.execute(task);
}
private static void loadProperties() {
try {
PROP_READER.loadProperties("Dummy");
} catch (final OODSystemException e) {
LOGGER.severe("Loading properties for app failed!");
}
}
private int getThreadPoolSize() {
return Integer.valueOf(PROP_READER
.getProperty(THREAD_POOL_SIZE));
}
}
While Mocking this class I am getting NullPointerException in the line PROP_READER.loadProperties("DUMMY");
My Test Case is:-
PowerMockito.whenNew(PropertyReader.class).withNoArguments().thenReturn(mockPropertyReader);
PowerMockito.doNothing().when( mockPropertyReader,"loadProperties",anyString());
mockStatic(ThreadPool.class);
First you need to set your internal state of your enum as enum is final class
and the instance of an enum will be load on class loading
ThreadPool mockInstance = mock(ThreadPool .class);
Whitebox.setInternalState(ThreadPool.class, "INSTANCE", mockInstance);
then
PowerMockito.mockStatic(ThreadPool .class);
and then mocking
doNothing().when(mockInstance).loadProperties(any(String.class));
do not forget adding the following annotation to the test
#RunWith(PowerMockRunner.class)
#PrepareForTest({ThreadPool.class})
if it still not working you need to see which more member of the class you need to set in the internal state
Let's consider the following simplified Resource hierarchy:
public abstract class Resource {
static public boolean accepts(String resource);
}
public class AudioResource extends Resource {
static public boolean accepts(String resource) {
//Check if we can proceed this resource as audio
//Some complex logic there ...
}
}
public class VideoResource extends Resource {
static public boolean accepts(String resource) {
//Check if we can proceed this resource as video
//Another complex logic there
}
}
Resource has dozens subclasses and number grows. Each sub-resource:
has some logic to determine if it accepts resource or not. E.g. it may parse resource URL with regexp or something;
is not singleton by design;
Now, we want to create a factory which iterates through all available subclasses and creates one which accepts resource (checks it using the accepts method).
Something like this (let's suppose for a moment that Java has static methods polymorphism):
public class ResourceFactory {
private static List<Class<Resource>> registry;
{
//Populate registry once on start
}
public static Resource createResource(String resource) {
for (Class<Resource> clazz : registry) {
if (clazz.accepts(resource))
return clazz.createInstance(resource);
}
}
}
Unfortunately (or not?), Java doesn't support polymorphic static methods. Considering that, what are the possible ways to design Resource and ResourceFactory?
You could use:
public interface Resource {
// some methods
}
public interface ResourceFactory {
boolean acceptsResource(String resource);
Resource createResource(String resource) throws UnsupportedResourceException;
}
public final MultiResourceFactory implements ResourceFactory{
private static final ServiceLoader<ResourceFactory > resourceFactoryLoader
= ServiceLoader.load(ResourceFactory .class);
private static final MultiResourceFactory INSTANCE;
private MultiResourceFactory(){
}
public static MultiResourceFactory getInstance(){
if (INSTANCE == null){
INSTANCE = new MultiResourceFactory();
}
return INSTANCE;
}
#Override
public boolean acceptsResource(String resource){
for (ResourceFactory resourceFactory : resourceFactoryLoader) {
if (resourceFactory.acceptsResource(resource)){
return true;
}
}
return false;
}
#Override
public Resource createResource(String resource) throws UnsupportedResourceException{
for (ResourceFactory resourceFactory : resourceFactoryLoader) {
if (resourceFactory.acceptsResource(resource)){
return resourceFactory.createResource(resource);
}
}
throw new UnsupportedResourceException(resource);
}
See ServiceLoader for how to register the factories:
http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
Note: the code is untested
I am trying to create a Singleton class, which will be accessed from two other classes.Can anyone please tell me whats wrong with the following code? I am just not able to figure out!
import java.util.LinkedList;
public class MessageQueue {
private static final LinkedList<ServerDataEvent> queue = new LinkedList<ServerDataEvent>();;
private static MessageQueue messageQueue = null;
/** A private Constructor prevents any other class from instantiating. */
private MessageQueue() {
}
/** Static 'instance' method */
public static MessageQueue getInstance() {
if (MessageQueue.messageQueue == null) {
System.out.println("Creating MessageQueue instance.");
MessageQueue.messageQueue = new MessageQueue();
}
return MessageQueue.messageQueue;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
I am accessing the singleton object from other classes like this:
MessageQueue messageQueue = MessageQueue.getInstance();
There are no errors, but
System.out.println("Creating MessageQueue instance.");
is getting executed whenever I do
MessageQueue messageQueue = MessageQueue.getInstance();
EDIT 1
import java.util.LinkedList;
public class MessageQueue {
private static final LinkedList<ServerDataEvent> queue = new LinkedList<ServerDataEvent>();;
private static final MessageQueue messageQueue = new MessageQueue();
/** A private Constructor prevents any other class from instantiating. */
private MessageQueue() {
System.out.println("problem...");
}
/** Static 'instance' method */
public static MessageQueue getInstance() {
return MessageQueue.messageQueue;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
First of all, you did not specify any errors you get. If you want to get help, you should give us as much information as you can.
Secondly, the best fool-proof way to create a singleton in Java is this:
public enum MySingleton {
INSTANCE;
//whatever methods you want to implement
}
and you access it like so: MySingleton.INSTANCE.whatever().
It is much better to define and instantiate your singleton object like this:
private static final MessageQueue messageQueue = new MessageQueue();
And then getInstance will be just:
public static MessageQueue getInstance() {
return MessageQueue.messageQueue;
}
This way your singleton object is instantiated and will be thread safe because it is created by the class loader.
A shorter version which is thread safe.
public enum MessageQueue {
INSTANCE;
private final Queue<ServerDataEvent> queue =
new ConcurrentLinkedQueue<ServerDataEvent>();
public void addEvent(ServerDataEvent event) { queue.add(event); }
}
or
public enum MessageQueue {
;
private static final Queue<ServerDataEvent> queue =
new ConcurrentLinkedQueue<ServerDataEvent>();
public static void addEvent(ServerDataEvent event) { queue.add(event); }
}
would be easier if you did it this way...
public class MessageQueue {
private static final MessageQueue INSTANCE= new MessageQueue();
public static MessageQueue getINSTANCE() {
return INSTANCE;
}
private MessageQueue() {
}
}
What's the error that occurs? All I can see from this is you have two semicolons here:
private static final LinkedList<ServerDataEvent> queue = new LinkedList<ServerDataEvent>();;
Simplest method:
private static final MessageQueue messageQueue = new MessageQueue();
public static MessageQueue getInstance() {
return MessageQueue.messageQueue;
}