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;
}
Related
I want to create a singleton in Java that requires reading from a file configuration to instanciate, amongst other logic (so it's not just a new MySingletonObject()).
What's the proper way to achieve that in Spring ? I was wondering if I should do the following:
public interface MySingletonObjectAccessor {
MySingletonObject getInstance();
}
#Service
public class MySingletonObjectAccessorImpl implements MySingletonObjectAccessor {
private MySingletonObject mySingletonObject;
#Override
public MySingletonObject getInstance() {
return mySingletonObject;
}
MySingletonObjectAccessorImpl() {
this.MySingletonObject = // complex logic here, that includes reading from a config file
}
}
the usage would then be:
#Autowired
MySingletonObjectAccessor msoa;
MySingletonObject mso = msoa.getInstance();
Am I on the right track ? If so, what would be the correct naming convention for the MySingletonObjectAccessor service ?
You can define a Bean and add a scope to make it singleton.
#Configuration
class MySingletonBeanConfiguration {
//default is singleton scope
#Bean
public MySingletonBean mySingletonBean() {
return new MySingletonBean();
}
}
You could have a public Configuration class like this in your Spring-scanned packages:
#Configuration
public class MySingletonProvider {
#Bean
public MySingleton nameTheMethodExactlyLikeTheBeanNameYouWant(#Value("${singleton.xml.file}") String xmlConfigFile) {
Library lib = new Library(xmlConfigFile);
return new MySingleton(lib);
}
}
If you are using singleton as config then use #Component and use #Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) for singleton.
If it is configuring a file the use FileConfig as class name, as per java standards class name must specify the what it have and what it can do. Ex:- FileReadConfig, FileUploadConfig, DBConnectConfig, EagerInitializedSingleton, StaticBlockSingleton, EnumSingleton ....,
Example:-
#Configuration
public class MySingletonObject {
private MySingletonObject mySingletonObject;
public static final String FILENAME = "/Users/xxx/Projects/xxx/config.xml";
private XMLObject config = null;
private boolean loadConfig(String fileName) {
BufferedReader reader;
String line;
String content = "";
try {
reader = new BufferedReader(new FileReader(fileName));
while ((line = reader.readLine()) != null) {
content += line;
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
return false;
}
/**
* IF there is no content, the file must not be valid
*/
if (content.length() <= 0) {
return false;
}
this.config = new XMLObject(content);
return true;
}
private Configuration() {
boolean result = this.loadConfig(FILENAME);
if (!result) {
if (!this.createConfig(FILENAME)) {
System.exit(0); //Catastrophic
}
}else{
mySingletonObject = new MySingletonObject ();
}
}
#Bean("mySingletonObject")
#Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public MySingletonObject getMySingletonObject () {
return mySingletonObject;
}
}
Now
#Autowired
MySingletonObject msoa;
My singleton is called Resources. It should only be instantiated once by this Singleton standard I used:
package site.kevindhu.models;
import site.kevindhu.entity.Player;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class Resources {
public static Resources resources;
public Map<String, Object> data;
static {
resources = new Resources();
}
private Resources() {
data = new HashMap<>();
data.put("players", new HashSet<Player>());
data.put("newPlayers", new HashSet<Player>());
}
public static Resources getInstance() {
return resources;
}
}
However, it is not working correctly!
When I deploy a .ear to run my glassfish server, it goes into this block twice:
static {
resources = new Resources();
}
As a result, the "singleton" actually creates two different Resources each time I run the server.
I know I do twice because I debug it calls two different Resources objects whenever I attempt to call Resources.resources.
Is this possibly because I am deploying a .ear file? How do the specifics of this double instantiation work?
The best way to go is to let the compiler handle it for you:
/** Singleton. */
public enum Resources {
RESOURCES;
private final Map<String, Team> teams = new HashMap<>();
public boolean add(Team team) {
return team != null
&& teams.put(team.getName(), team) == null;
}
public Team find(String name) {
return name == null ? null : teams.get(name);
}
public Team find(Team team) {
return team == null ? null : get(team.getName());
}
public Map<String, Team> getTeams() {
return Collections.unmodifiableMap(teams);
}
// remove, iterators, etc.
}
public class TeamImpl implements Team {
private final String name;
private final Map<String, Player> roster = new HashMap<>();
public TeamImpl(String name) {
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
this.name = name;
assert this.name != null;
}
#Override
public boolean equals(Object other) {
// base comparison on team name
}
#Override
public int hashCode() {
assert this.name != null;
return name.hashCode();
}
// methods from interface Team:
#Override
public String getName() {
return name;
}
#Override
public Set<Player> getRoster() {
return Collections.unmodifiableSet(new HashSet<>(roster.values()));
}
#Override
public boolean add(Player player) {
return player != null
&& roster.put(player.getName(), player) == null;
}
#Override
public Player find(String name) {
return name == null ? null : roster.get(name);
}
// remove, iterators, etc.
}
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();
}
}
In my GWT web application I have a textbox that holds a price.
How can one convert that String to a BigDecimal?
The easiest way is to create new text box widget that inherits ValueBox.
If you do it this way, you won't have to convert any string values manually. the ValueBox takes care of it all.
To get the BigDecimal value entered you can just go:
BigDecimal value = myTextBox.getValue();
Your BigDecimalBox.java:
public class BigDecimalBox extends ValueBox<BigDecimal> {
public BigDecimalBox() {
super(Document.get().createTextInputElement(), BigDecimalRenderer.instance(),
BigDecimalParser.instance());
}
}
Then your BigDecimalRenderer.java
public class BigDecimalRenderer extends AbstractRenderer<BigDecimal> {
private static BigDecimalRenderer INSTANCE;
public static Renderer<BigDecimal> instance() {
if (INSTANCE == null) {
INSTANCE = new BigDecimalRenderer();
}
return INSTANCE;
}
protected BigDecimalRenderer() {
}
public String render(BigDecimal object) {
if (null == object) {
return "";
}
return NumberFormat.getDecimalFormat().format(object);
}
}
And your BigDecimalParser.java
package com.google.gwt.text.client;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.text.shared.Parser;
import java.text.ParseException;
public class BigDecimalParser implements Parser<BigDecimal> {
private static BigDecimalParser INSTANCE;
public static Parser<BigDecimal> instance() {
if (INSTANCE == null) {
INSTANCE = new BigDecimalParser();
}
return INSTANCE;
}
protected BigDecimalParser() {
}
public BigDecimal parse(CharSequence object) throws ParseException {
if ("".equals(object.toString())) {
return null;
}
try {
return new BigDecimal(object.toString());
} catch (NumberFormatException e) {
throw new ParseException(e.getMessage(), 0);
}
}
}
Take a look at GWT-Math.
I'm having an issue with my configuration management class, it is not getting reloaded.
Let me show you part of my code:
public class ConfigurationManager extends XMLConfiguration
{
private static final Logger log = LoggerFactory.getLogger(ConfigurationManager.class);
private static final long serialVersionUID = 1L;
public static final String CONFIG_FILE_PATH = "/config.xml";
private static volatile ConfigurationManager instance = null;
private static Object lock = new Object();
// Instance management methods
public static ConfigurationManager getInstance()
{
return getInstance(CONFIG_FILE_PATH);
}
public static ConfigurationManager getInstance(String cfg)
{
if(instance == null)
{
synchronized(lock)
{
if(instance == null)
{
try
{
instance = new ConfigurationManager(cfg);
instance.dumpConfigurationToLog();
}
catch(Exception e)
{
log.error("Error calling getInstance. Method params", e);
}
}
}
}
return instance;
}
private Object loadedCfg;
private int reloadInterval;
private void dumpConfigurationToLog()
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
this.save(bos);
bos.flush();
}
catch(Exception e)
{
log.error("Error calling dumpConfigurationToLog. Method params", e);
}
}
#Override
public void configurationChanged(ConfigurationEvent event)
{
log.info("Enter Method configurationChanged params: {}", event);
if(event.isBeforeUpdate() == false)
{
makeUpdates();
log.info("Configuration file: {} has changed and reloaded...", loadedCfg);
dumpConfigurationToLog();
}
log.info("Return Method configurationChanged");
}
private void updateReloadInterval()
{
int newReloadInterval = getInt("global.reloadInterval") * 1000;
if(reloadInterval != newReloadInterval)
{
reloadInterval = newReloadInterval;
if(getReloadInterval() > 0)
{
FileChangedReloadingStrategy reloadStrategy = new FileChangedReloadingStrategy();
reloadStrategy.setRefreshDelay(getReloadInterval());
this.setReloadingStrategy(reloadStrategy);
}
else
if(getReloadInterval() == 0)
{
this.setReloadingStrategy(new InvariantReloadingStrategy());
}
else
{
log.error("Invalid reload interval for ConfigurationManager: {}", getReloadInterval());
}
}
}
private ConfigurationManager(String cfgFile) throws Exception, ConfigurationException
{
super();
loadedCfg = cfgFile;
if(System.class.getResource(cfgFile) != null)
this.setURL(System.class.getResource(cfgFile));
else
this.setURL(getClass().getResource(cfgFile));
this.load();
makeUpdates();
this.addConfigurationListener(this);
this.setThrowExceptionOnMissing(true);
}
private void makeUpdates()
{
updateReloadInterval();
}
public int getReloadInterval()
{
return reloadInterval;
}
}
Now that code works perfectly fine, I can read the configuration file, and work with it with no major problems, the issue is that it never gets reloaded on configuration changes. I've tried setting breakpoints and so, but it never gets into configurationChanged method.
Does anybody see something wrong here?
Well, after testing and analyzing, I've got to this conclusion, in order to have configurationChanged called, I need to make an explicit call to get values from configuration.
And that is something I was not doing.
The thing got fixed when I did that.
You're calling makeUpdates() after setting your ConfigurationListener.
Additionally, calling load() is no guarantee that an Event will get fired.
Lastly, is there anything actually calling addProperty(), etc for this extended class?
Only a small side issue: resource bundles are cached, you can call clearCache, unfortunately not per bundle but per class loader.