See this incomplete code fragment:
public class Singleton implements Serializable {
private static class SingletonHolder {
private static final Singleton SINGLETON_INSTANCE;
static {
Singleton tmp = singletonTMP;
if (tmp != null) {
SINGLETON_INSTANCE = tmp;
} else {
// etc.
}
}
}
private static volatile Singleton singletonTMP;
// etc.
}
I get a strange warning in NetBeans at line Singleton tmp = singletonTMP;: "Usage of static non-final variable used during initialization".
So, yes. This is true, of course, but why would this be a problem?
The problem is that the variable :
private static final Singleton SINGLETON_INSTANCE;
might not have been initialized in that static block of yours, you can inititalize it to null(say) in the else clause inside that static block, i.e:
static
{
Singleton tmp = singletonTMP;
if (tmp != null)
{
SINGLETON_INSTANCE = tmp;
} else
{
**SINGLETON_INSTANCE = null;**
}
}
After reading a bit about security I think my previous comment was correct.
I think it is a security issue, an attacker could replace your static field with a new object. This happens when the attribute is also defined as public. I assume netbeans considers it a risk and displays the warning even if you declared it private.
More details here:
https://www.securecoding.cert.org/confluence/display/java/OBJ10-J.+Do+not+use+public+static+nonfinal+variables
Related
Error:
...
Caused by: java.lang.ExceptionInInitializerError
...
Caused by: java.lang.ClassCastException:
class com.evopulse.ds2150.TechTrees$BuildingTechTree
not an enum
at java.util.EnumSet.noneOf(Unknown Source)
at java.util.EnumSet.of(Unknown Source)
at com.evopulse.ds2150.TechTrees$BuildingTechTree.<clinit>(TechTrees.java:38)
Here is a snippet of my enumeration
public enum BuildingTechTree {
//Name SoftName Requirements
NONE ("NULL", null),
--> This next line is where it crashes
BARRACKS ("Barracks", EnumSet.of(NONE),
WALLS_SANDBAGS ("Sandbag wall", EnumSet.of(NONE),
POWERPLANT ("Power plant", EnumSet.of(BARRACKS)),
GUARDTOWER ("Guard Tower", EnumSet.of(BARRACKS));
Replacing EnumSet.of(NONE) and EnumSet.of(BARRACKS) with null, lets initialization work, but breaks my code, due to missing data structure... obviously, but I did it to test the rest of my code wasn't somehow the cause.
Removing EnumSet.of(NONE) and replacing with just NONE, and the same for BARRACKS, and changing all related variables, constructor, and methods, that didn't work either... (and even couldn't use the contains.all, since is wasn't "applicable to my changed variable"... )
I extended this example, using the second implementation:
https://gamedev.stackexchange.com/a/25652/48573
I also tried retracing my steps by copying the example verbatim. added
private static Set<BuildingTechTree> techsKnown;
techsKnown = (BuildingTechTree.BIODOME);
test = TechTrees.researchTech(techsKnown);
to another class to be called from for testing initialization. and had to change
public boolean researchTech(BuildingTechTree tech) {
to static
This resulted in the same "in not an enum" error. I don't have any rep, to comment on his answer to point out the initialization error...
Added info for both current answers, as both solutions cause the same new error:
public class TechTrees {
private static Set<BuildingTechTree> techsKnown;
public TechTrees() {
techsKnown = EnumSet.of(BuildingTechTree.NONE); //Using this
techsKnown = EnumSet.noneOf(BuildingTechTree.class); //Or this
}
public static boolean researchTech(BuildingTechTree tech) {
if (techsKnown.containsAll(tech.requirements)) { //Causes null pointer
return true; //exception # techsKnown
}
return false;
}
Your declaration structure is so clever it's a shame it doesn't work. But EnumSet apparently needs the enum to be fully initialized first. It tries to fetch the array of constants from the enum so that, among other things, it knows how much space is needed for its internal bitset.
Here's one workaround. It uses a helper method that creates an ordinary set (HashSet) first, and then, in a static initialization block, it iterates the enum constants and replaces all the sets with EnumSets.
public enum BuildingTechTree {
// Named constants
//Name SoftName Requirements
NONE ("NULL", null),
BARRACKS ("Barracks", setOf(NONE)),
WALLS_SANDBAGS ("Sandbag wall", setOf(NONE)),
POWERPLANT ("Power plant", setOf(BARRACKS)),
GUARDTOWER ("Guard Tower", setOf(BARRACKS));
private final String softName;
private Set<BuildingTechTree> requirements;
private BuildingTechTree(String softName, Set<BuildingTechTree> requirements) {
this.softName = softName;
this.requirements = requirements;
}
private static Set<BuildingTechTree> setOf(BuildingTechTree... values) {
return new HashSet<>(Arrays.asList(values));
}
static {
for (BuildingTechTree v : values()) {
if (v.requirements == null) {
v.requirements = EnumSet.noneOf(BuildingTechTree.class);
} else {
v.requirements = EnumSet.copyOf(v.requirements);
}
}
}
}
You have a chicken and egg problem. You could refactor your enum to something like this:
public enum BuildingTechTree {
NONE("NULL"),
BARRACKS("Barracks"),
WALLS_SANDBAGS("Sandbag wall"),
POWERPLANT("Power plant"),
GUARDTOWER("Guard Tower");
static {
NONE.trees = EnumSet.noneOf(BuildingTechTree.class);
BARRACKS.trees = EnumSet.of(NONE);
WALLS_SANDBAGS.trees = EnumSet.of(NONE);
POWERPLANT.trees = EnumSet.of(BARRACKS);
GUARDTOWER.trees = EnumSet.of(BARRACKS);
}
private String name;
private Set<BuildingTechTree> trees;
private BuildingTechTree(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Set<BuildingTechTree> getTrees() {
return Collections.unmodifiableSet(trees);
}
}
EDIT:
regarding your second problem: you're accessing a static variable, from a static method. But this variable is initialized when the constructor of the class has been called (which is a huge design problem). Don't use non-final static fields. And don't initialize static fields from instance methods or constructors. That doesn't make sense. You don't set the color that all cars should have when constructing a car. Initialize your static fields statically:
public class TechTrees {
private static final Set<BuildingTechTree> TECHS_KNOWN =
EnumSet.of(BuildingTechTree.NONE);
public static boolean researchTech(BuildingTechTree tech) {
return TECHS_KNOWN.containsAll(tech.requirements));
}
}
I am new to Java and started learning and exploring bit about language. Could anyone explain what is significance of _() in that constructor. Is that called constructor?
public class UserRequestCache {
private final static ThreadLocal <UserRequest> t = new ThreadLocal <UserRequest>();
private static UserRequestCache instance = new UserRequestCache();
public static UserRequestCache _() {
return instance;
}
private UserRequestCache() {
}
public void checkPoint() {
if (logDebug()) {
if (getUserRequest() != null) {
logDebug(getUserRequest().toString());
}
}
}
public UserRequest getCache() {
// checkPoint();
return getUserRequest();
}
private UserRequest getUserRequest() {
return t.get();
}
public void setCache(UserRequest value) {
t.set(value);
}
}
No, it's just a very poorly named method. I recall another similar question recently, that quoted some documentation saying that even though a single underscore is a legal name, it shouldn't be used.
In this case it seems that the class is a Singleton, and the method that's usually named getInstance() has been shortened to _().
It's a funny construct that you have here. the name of the function is '_'.
So you have something like UserRequestCache._() that return a UserRequestCache.
Nothing to do with some weird Java 'magic'
Here is my code.
public class PropertyLoader {
private Properties appProperties;
/**
* The instance.
*/
private static PropertyLoader inst = null;
/**
* Instantiates a new property data loader.
*/
private PropertyLoader() {
try
{
appProperties = new Properties();
appProperties.load(this.getClass().getClassLoader().getResourceAsStream("app.properties"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static PropertyLoader getInstance() {
if (inst == null) {
inst = new PropertyLoader();
}
return inst;
}
}
public String getPropertyAPP(String key) {
return appProperties.getProperty(key);
}
}
Synchronization is needed for the getPropertyAPP method: it is a singleton, so many threads can access the same instance simultaneously and call it.
Can anyone suggest me the right way?
you can use following solution
public class PropertyLoader {
private Properties appProperties;
/** The instance. */
private static PropertyLoader inst = null;
static{
inst = new PropertyLoader();
}
/**
* Instantiates a new property data loader.
*/
private PropertyLoader() {
try
{
appProperties = new Properties();
appProperties.load(this.getClass().getClassLoader().getResourceAsStream("app.properties"));
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static PropertyLoader getInstance() {
return inst;
}
public String getPropertyAPP(String key) {
return appProperties.getProperty(key);
}
}
A simpler solution, which is also thread safe, is to use static initialisation to initialise a static field.
public class AppProperties {
private static final Properties appProperties;
static {
try {
appProperties = new Properties();
appProperties.load(AppProperties.class
.getClassLoader().getResourceAsStream("app.properties"));
} catch(IOException e) {
e.printStackTrace();
}
}
public String get(String key) {
return appProperties.getProperty(key);
}
public String get(String key, String defaultValue) {
return appProperties.getProperty(key, defaultValue);
}
}
You have a massive race condition happening in your getInstance() method. If more than one threads call getInstance() at the same time you will create multiple instances and assign them in turn to the static variable. Considering what you're doing here this won't cause any logic problems, but does mean you're doing more work than necessary.
I recommend you do some reading about the Singleton pattern, why it's bad, and how to implement it in a safe way in Java.
But in short, don't use the Singleton pattern, it's hideously broken and will make any code that uses this object tightly-coupled and will inhibit your ability to do any kind of isolated testing.
Several issues with your code:
(a) Are you sure you need lazy initialisation? The cost of initialisation must be noticeable and the chance that the resource is never used must be non-zero. Also: it may be preferable to fail during program start rather than at some indeterminate moment later when the resource is first accessed. This really depends on your application.
(b) One way of implementing the lazy initialisation is using the correct version of double checked locking (the volatile keyword is essential):
private static volatile PropertyLoader inst;
...
public static PropertyLoader getInstance() {
if (inst == null) {
synchronized(PropertyLoader.class) {
if (inst == null) {
inst = new PropertyLoader();
}
}
}
return inst;
}
This wikipedia article explains why this works (as of Java 5 but nore before): http://en.wikipedia.org/wiki/Double-checked_locking
(c) Catching exceptions and simply logging them is plain wrong under most circumstances. In your case, no property would ever be returned from getPropertyAPP. This may be ok if the presence of the properties is clearly declared to be optional.
I wrote a below Singleton class. I am not sure whether this is thread safe singleton class or not?
public class CassandraAstyanaxConnection {
private static CassandraAstyanaxConnection _instance;
private AstyanaxContext<Keyspace> context;
private Keyspace keyspace;
private ColumnFamily<String, String> emp_cf;
public static synchronized CassandraAstyanaxConnection getInstance() {
if (_instance == null) {
_instance = new CassandraAstyanaxConnection();
}
return _instance;
}
/**
* Creating Cassandra connection using Astyanax client
*
*/
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("127.0.0.1:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
/**
* returns the keyspace
*
* #return
*/
public Keyspace getKeyspace() {
return keyspace;
}
public ColumnFamily<String, String> getEmp_cf() {
return emp_cf;
}
}
Can anyone help me with this? Any thoughts on my above Singleton class will be of great help.
Updated Code:-
I am trying to incorporate Bohemian suggestion in my code. Here is the updated code, I got-
public class CassandraAstyanaxConnection {
private static class ConnectionHolder {
static final CassandraAstyanaxConnection connection = new CassandraAstyanaxConnection();
}
public static CassandraAstyanaxConnection getInstance() {
return ConnectionHolder.connection;
}
/**
* Creating Cassandra connection using Astyanax client
*
*/
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("127.0.0.1:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
/**
* returns the keyspace
*
* #return
*/
public Keyspace getKeyspace() {
return keyspace;
}
public ColumnFamily<String, String> getEmp_cf() {
return emp_cf;
}
}
Can anyone take a look and let me know if this time I got it right or not?
Thanks for the help.
You are implementing the lazy initialization pattern - where the instance is created when first used.
But there is a simple trick that allows you to code a threadsafe implementation that doesn't require synchronization! It is known as the Initialization-on-demand holder idiom, and it looks like this:
public class CassandraAstyanaxConnection {
private CassandraAstyanaxConnection(){ }
private static class Holder {
private static final CassandraAstyanaxConnection INSTANCE = new CassandraAstyanaxConnection();
}
public static CassandraAstyanaxConnection getInstance() {
return Holder.INSTANCE;
}
// rest of class omitted
}
This code initializes the instance on the first calling of getInstance(), and importantly doesn't need synchronization because of the contract of the class loader:
the class loader loads classes when they are first accessed (in this case Holder's only access is within the getInstance() method)
when a class is loaded, and before anyone can use it, all static initializers are guaranteed to be executed (that's when Holder's static block fires)
the class loader has its own synchronization built right in that make the above two points guaranteed to be threadsafe
It's a neat little trick that I use whenever I need lazy initialization. You also get the bonus of a final instance, even though it's created lazily. Also note how clean and simple the code is.
Edit: You should set all constructors as private or protected. Setting and empty private constructor will do the work
all above methods are eagerly initializing object. how about this. This will help you to initialize ur class lazily. You may have heavy object and you don't want to initialize on startup.
public class MySinglton {
private MySinglton (){}
private static volatile MySinglton s;
public static MySinglton getInstance(){
if (s != null ) return s;
synchronized(MySinglton.class){
if (s == null ) {
s = new MySinglton();
}
}
return s;
}
}
As mentiond in this great article here :
The best solution to this problem is [...] to use a static field
public class Singelton {
private static final Singelton singleObject = new Singelton();
public Singelton getInstance(){
return singleObject;
}
}
No, its not thread-safe if the values returned on the pulbic methods are changeble objects.
To this class be Thread-safe one way is to change it to be immutable.
To do that, you could change this methods like this:
public Keyspace getKeyspace() {
// make a copy to prevent external user to modified or ensure that Keyspace is immutable, in that case, you don't have to make a copy
return new Keyspace( keyspace );
}
public ColumnFamily<String, String> getEmp_cf() {
// Same principle here. If ColumnFamily is immutable, you don't have to make a copy. If its not, then make a copy
return new ColumnFamily( emp_cf );
}
In this book Java Concurrency in Practice you can see the principle of that immutability.
No, this does not appear to be thread-safe. It appears that you there is mutable data accessible after the call to getInstance, where the lock would have been released.
This should be the correct way to implement Singleton pattern using double checked locking principle:
class MySinglton {
private static volatile MySinglton instance;
private MySinglton() {}
public static MySinglton getInstance() {
if (instance == null) {
synchronized (MySinglton.class) {
if (instance == null) {
instance = new MySinglton();
}
}
}
return instance;
}
}
I think this will do the same thing without having to check for instance every time. static is the same as check first time
public class Singl {
private static Singl _instance;
//other vars
static{
//synchronized(Singl.class){//do not need
_instance = new Singl();
//}
}
public static Singl getInstance() {
return _instance;
}
private Singl(){
//initizlize
}
}
After java 1.5 version we can use volatile. If we used volatile java key ward, we can create singlton class with thread safe, Because instance variable share with Other thread as well.
public class SingleWithThreadSafe {
// create an object static referance of SingleWithThreadSafe with volatile
private static volatile SingleWithThreadSafe instance = null;
// if we make the constructor private so that this class cannot be
// instantiated from out side of class
private SingleWithThreadSafe() {
}
// Get only object available
public static SingleWithThreadSafe getInstance() {
if (instance == null) {
instance = new SingleWithThreadSafe();
}
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
I've defined the following enum in Groovy, though for the purpose of this question it could be Java code:
enum FestivalType {
BIG_MUSIC,
SMALL_MUSIC,
FILM,
FOOD_AND_DRINK;
private static Set<String> allSearchTokens = new HashSet<String>();
FestivalType() {
String searchToken = this.name().tokenize('_').first().toLowerCase();
if (searchToken in allSearchTokens) {
throw new RuntimeException("Duplicate search token");
} else {
this.searchToken = searchToken;
allSearchTokens.add(searchToken);
}
}
final String searchToken;
}
What I'm trying to do in the constructor is establish whether the first token in the name of each enum constant is unique, where _ is used as the token separator.
However, this code doesn't work because allSearchTokens is not initialized until after all the constants are instantiated, so I get a NullPointerException here
allSearchTokens.add(searchToken)
You can work around this as follows:
public enum FestivalType {
BIG_MUSIC,
SMALL_MUSIC,
FILM,
FOOD_AND_DRINK;
private static class SetHolder {
static Set<String> allSearchTokens = new HashSet<String>();
}
final String searchToken;
FestivalType() {
String searchToken = name().split("_")[0].toLowerCase();
if (SetHolder.allSearchTokens.contains(searchToken))
throw new RuntimeException("Duplicate search token");
this.searchToken = searchToken;
SetHolder.allSearchTokens.add(searchToken);
}
}
This compiles because of the java specification that all static initializers must be completed before the class is used. By making the Set a static field of a sttic inner class, you guarantee that it will be initialized before the first enum is constructed.
Also, I took the liberty of changing/fixing a few things in your code:
Use a Set rather than a List: Values are unique
Use split(): There is not such method tokenize() for String in java
Remove else: After a return or throws, else is always redundant because execution of the block is halted by these keywords (there is no "else" to handle)
As an aside, this technique is also great for lazy initialization of singletons:
public class MyLazySingleton() {
private static class InstanceHolder {
static MyLazySingleton INSTANCE = new MyLazySingleton();
}
public static MyLazySingleton getInstance() {
return InstanceHolder.INSTANCE;
}
}
The INSTANCE field is only constructed when the getInstance() method is first called!
Look mom! Lazy initialization without locks, without null checks, without synchronization of any kind and 100% bulletproof! (Object deserialization hacks notwithstanding)
It's magic :)
I have done something similar and the following has worked for me:
enum MyEnum{
Enum1, Enum2;
private static List<String> myList;
private static void addToList(MyEnum enum){
if(myList == null){
myList = new ArrayList<String>();
}
myList.add(enum.name());
}
private MyEnum(){
addToList(this);
}
}