Validity of the concurrency test for instance and static methods - java

I wanted to validate the below test I wrote to validate the fact that two threads can concurrently access a static synchronized method and a non-static synchronized method (as locks is on different objects). I got a result but wanted to know if my interpretation is correct or not
I ran the below code and I saw same value for variable i being printed at times from static and non-static method respectively. Is this a valid proof of the fact that static and non-static methods have locks on two different objects and two threads can access them simultaneously.
Code
import java.util.ArrayList;
import java.util.List;
public class TestStaticSynchronize {
public static final TesteeClass obj = new TesteeClass();
/**
* #param args
*/
public static void main(String[] args) {
for(int i = 0; i < 50; i++) {
Runner run = new Runner(i);
Thread th = new Thread(run);
th.start();
}
}
static class Runner implements Runnable {
private int i;
public Runner(int i) {
this.i = i;
}
public void run() {
if(i % 2 == 0) {
TesteeClass.staticSync();
} else {
obj.instanceSync();
}
}
}
}
class TesteeClass {
private static List<Integer> testList = new ArrayList<Integer>();
public static synchronized void staticSync() {
System.out.println("Reached static synchronized method " + testList.size());
testList.add(1);
}
public synchronized void instanceSync() {
System.out.println("Reach instance synchronized method " + testList.size());
testList.add(1);
}
}

Your assessment is correct. Here's why.
So take your synchronized instance method and let's rewrite it in equivalent synchronized block notation:
public void instanceSync() {
synchronized( this ) {
System.out.println("...");
testList.add( 1 );
}
}
When you write a synchronized method it's the same thing as locking on the surrounding instance (i.e. this). With static methods this parameter does not exist so what is the equivalent synchronized block for statics? It's locking on the Class object.
public void classSync() {
synchronized( TestClass.class ) {
System.out.println("...");
testList.add( 1 );
}
}
So the instance this is different object from the object representing the TestClass class. That means there are two different locks being used which leads to the problems you discovered. In the end your test program is very dangerous and not thread safe. Instance methods, especially when used in multi-threaded situations, should NOT touch static members period. It's fine to route those accesses through static methods, but direct access is at best poor form at worse a serious bug.
There is a way to write your program in a way that they both lock on the same object, but I think it's important you consider why you are write code like this. Is it because you really only want lots of places to share a single structure like this, but have trouble getting a reference to a single object? This gets at the heart of software architecture and the important role it plays in multi-threaded applications. I suspect there is a much better option for you than using static members, and just use a single instance that all locations have a reference too (hopefully not using singleton pattern, global statics, etc).

Related

how can i use java scanner with lazy singeleton?

i want to make 2 input scanner in java with Lazy singeleton algorithm..
and print it..
the question is : write a java program to get username and password then print it(with Lazy singeleton algorithm)
import java.util.Scanner;
public class lazy1 {
String a1;
String a2;
private static lazy1 Instance;
public synchronized static lazy1 getInstance() {
if (Instance == null) {
Instance = new lazy1();
}
return Instance;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("uesrname");
String a1 = sc.nextLine();
System.out.println("password");
String a2 = sc.nextLine();
System.out.println("username : "+ a1);
System.out.println("password : "+ a2);
}
}
lazy singletons are completely useless*. The aim is, presumably, that the singleton is not 'initialized' or 'takes up memory'. But, good news! It won't. Not until some code touches the singleton class, at which point, well, you needed that initialization anyway. Thus:
public class Lazy1 {
private static final Lazy1 INSTANCE = new Lazy1();
private Lazy1() {} // prevent instantiation by anybody else
public static Lazy1 getInstance() { return INSTANCE; }
}
Does what you want: It is simpler, not buggy, and fast. In contrast to your take, which is quite slow (a synchronized lock every time, even on hour 100, after a million calls to getinstance. However, remove the synchronized and you end up in a buggy scenario. You can try to get around that in turn with volatiles and double locking, but now you have quite complicated code that is almost impossible to test, and which still cannot outperform the fast locking that the classloader itself gives you).
You may think this is non-lazy, but that's false. Try it: print something in that constructor and observe when it prints. It'll print only when the first getInstance() is ever invoked.
Given that it is a singleton, if you need some property (such as 'a scanner') to operate, you have only two options:
The singleton is in an invalid state until it is initialized
All methods that need this state check if the state is valid and throw if it is not:
public class Lazy1 {
private static final Lazy1 INSTANCE = new Lazy1();
private Lazy1() {} // prevent instantiation by anybody else
public static Lazy1 getInstance() { return INSTANCE; }
private Scanner scanner;
public void menu() {
if (scanner == null) throw new IllegalStateException("Uninitialized");
// ....
}
public void init(Scanner s) {
this.scanner = s;
}
}
Every method that needs the 'scanner state' should first check, then throw.
The singleton doesn't have state. Instead, its methods take the required state as parameter
Your Lazy1 doesn't have, say, public void menu(). It has public void menu(Scanner s) {} - every time any code calls it, it passes scanner along.
*) There is actually a point, but only if some code refers to the Lazy1 class without getting the singleton. If you're doing that, you probably need to fix your code; that'd be rather weird.

Static syncronized method and non-static synchronized method can both work on static member variables and this can cause unexpected behaviour

I syncronized a static method and a non-static method as follows:
public class Demo {
static int myvalue;
synchronized static public void getStatic() {
myvalue = 2;
}
synchronized public void get() {
myvalue = 1;
}
}
Then from the Thread 1 I called only the static method and from the Thread 2 I called only the non-static method.
As one call is locked on the object and the other on the class, there is no waiting to get the lock.
So, that means that both the functions can run at the same time.
Now, the fact is that both the functions work on static member variables (myvalue in the example). That can be a problem in a multi-threading application. Why do the Java creators didn't take this into account? What can be the right way of dealing with this type of situation?
Why do the Java creators didn't take this into account?
They did, and thats why you have option to sync on a class and object levels.
What can be the right way of dealing with this type of situation?
You must use synchronized(Demo.class) {...} in your get() method.
Synchronized on a single object or class, e.g.
public class Demo {
static int myvalue;
static public void getStatic() {
synchronized(Demo.class) {
myvalue = 2;
}
}
public void get() {
synchronized(Demo.class) {
myvalue = 1;
}
}
}

The static field should be accessed in a static way

I have different Exception category Enum as below
public enum GSBBCacheCategory {
SEARCH(9001),
UPDATE_PERSECURITY(9002),
CROSS_REFERENCING_PERSECURITY(9003),
METADATA_SEARCH(9004),
REMOVEALL(9005),
UPDATE_BACKOFFICE(9002);
private int exceptionCode;
GSBBCacheCategory(int exceptionCode)
{
this.exceptionCode = exceptionCode;
}
public int getExceptionCode()
{
return exceptionCode;
}
}
public enum GSBBEncryptionCategory {
.
.
.
}
I want to provide one place to access these Enum in client code. Presently I achieved this as below
public class GSBBExceptionCodes
{
public static GSBBDecryptionCategory decryptionCategory;
public static GSBBCacheCategory cacheCategory;
}
Now to access exception code I have do something like below
public static void main(String[] args) {
System.out.println(GSBBExceptionCodes.decryptionCategory.ERRORCODE_DECRYPTION_FAILURE);
System.out.println(GSBBExceptionCodes.cacheCategory.UPDATE_PERSECURITY);
}
Which says “The static field GSBBDecryptionCategory.ERRORCODE_DECRYPTION_FAILURE should be accessed in a static way”
Is it possible to achieve above without any warning?
There are two ways to reference a static member (either a field or a method). One is WhateverClass.theField, and the other is someInstance.theField where someInstance has a compile-time type of WhateverClass. The former is much clearer, and so your IDE is helpfully telling you to use it instead of the latter.
The reason it's better is that referencing a static member by an instance makes it look like the method has something to do with that instance, which it doesn't. Here's a real-life example:
Thread myThread = getMyThread();
myThread.start();
myThread.sleep(5000);
At first blush, it looks like you're asking myThread to sleep for 5 seconds (5000 milliseconds), but that's not what you're doing at all. You're asking the current thread to sleep, because that last line is exactly the same as invoking Thread.sleep(5000). That second example is much more clearly a static method.
Or, here's another example. Let's say your static fields were mutable.
public class Foo {
public static int value = 1;
}
(This public static mutable field is a bad idea for other reasons, but simplifies the example). Now let's say you do:
Foo one = new Foo();
Foo two = new Foo();
one.value = 2;
two.value = 3;
System.out.println(one.value);
System.out.println(two.value);
Kinda looks like that should print "2" and then "3", right? But no -- it'll print "3", "3" because both assignments to .value are in fact to the same, static field. It's just an optical illusion that the one or two instances have anything to do with anything.
Imho, the ability to reference static members from instances is a misfeature. But it's there, so you should avoid it. Which is what the compiler is trying to suggest you do.
Try this :
public static void main(String[] args) {
System.out.println(GSBBDecryptionCategory.ERRORCODE_DECRYPTION_FAILURE);
System.out.println(GSBBCacheCategory.UPDATE_PERSECURITY);
}
You are now accessing the field in a static way which should remove the warning.
It sounds like instead of having these as public static fields, they should be inner classes:
public class GSBBExceptionCodes {
public enum GSBBCacheCategory {
...
}
}

Correct use of Singleton Pattern

I am trying to implement an example of the singleton pattern. One of our questions is to run two threads each calling getInstance() and to verify only one instance of the Singleton object was created.
Here is my Singleton code;
public class OurSingleton {
static OurSingleton ourSingleton;
static int instanceCounter;
private OurSingleton(){
instanceCounter++;
}
public static synchronized OurSingleton GetSingletonInstance(){
if( ourSingleton == null){
ourSingleton = new OurSingleton();
}
return ourSingleton;
}
public static int getCounter() {
return instanceCounter;
}
}
And my main;
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
OurSingleton mySingleton = null;
Thread one = new Thread(new GetSingletonInstance(mySingleton));
Thread two = new Thread(new GetSingletonInstance(mySingleton));
one.start();
two.start();
System.out.println("Main: " + mySingleton.getCounter());
}
}
class GetSingletonInstance implements Runnable {
int count = 0;
OurSingleton singleton;
public GetSingletonInstance(OurSingleton ourSingleton){
singleton = ourSingleton;
}
#Override
public void run() {
try {
while (count < 5000000) {
singleton.getSingletonInstance();
count++;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread: " + singleton.getCounter());
}
}
When I run this code I get the following output;
Main: 0 Thread: 1 Thread: 1
Can somebody explain the reason for this output? I thought only a single instance of Singleton existed across the board. Does this mean another object is being created in the threads ?? Any advice is appreciated !
You should avoid synchronizing the getInstance method (because it's just an unnecessary overhead just to get the instance once it has been initialized). Following is the recommended way for lazy-initializing singleton:
public class OurSingleton {
private OurSingleton() { }
public static OurSingleton getInstance() {
return Holder.instance;
}
private static class Holder {
private static OurSingleton instance = new OurSingleton();
}
}
thought only a single instance of Singleton existed across the board.
Does this mean another object is being created in the threads ??
Only one instance of singleton exists in the JVM; each of your threads displays the fact that there is only one instance.
The easiest and safest way to implement the Singleton Pattern in Java is by using enums:
public enum MySingleton {
INSTANCE;
public void doStuffHere() {
//...
}
}
public class ClientClass {
public void myMethod() {
MySingleton mySingleton = MySingleton.INSTANCE;
mySingleton.doStuff();
}
}
You have only one instance of MySingleton and it is thread-safe.
You have created 2 instances of thread from the same class. Each one prints number of instances of your singleton object. The number is 1 that means that you indeed created only one instance, so that your singleton is implemented correctly.
You printed this twice because you created 2 threads.
If you want to avoid confusing move line System.out.println(...) to your main method.
There is only one OurSingleton instance, but the class getSingletonInstance (USE PROPER CAPS!) is not a singleton itself. And it is the one where you put the counter.
I would explain this so:
When you loaded the class OurSingleton, the static counter getInstanceCounter is initialized to zero.Then how many ever times you get a new instance of the class, the counter is always 1, indicating that you have indeed a singleton.
I would suggest making the following changes
Make the static variables in Singleton private: ourSingleton, getInstanceCounter
Remove the synchronized keyword on the method, since its an unnecessary overhead
Look at the other answer for how to do this better, for your question why are you getting this output
Main: 0
Thread: 1
Thread: 1
with the code
static int getInstanceCounter;
you are setting declaring and setting an static variable to zero. So before any instance of OurSingleton has been created getInstanceCounter has a value of zero.
When you call
System.out.println("Main: " + mySingleton.getCounter());
No instance of OurSignleton has been created so mySignleton.getCounter() is still zero.
Running of either or both threads will cause one instance of OurSingleton to be created and getInstanceCounter will be one.
Your singleton is working. Though better ways have been mentioned in other answers.
As an aside a few things about your code which may seem nit picky but will help other people read your code.
Please make variable private
static int getInstanceCounter; =>
private static int getInstanceCounter;
Variables should not be named with get
private static int getInstanceCounter; =>
private static int instanceCounter;
Don't refer to static methods on an instance of a class
mySingleton.getCounter() =>
OurSingleton.getCount()
This also means that the variable mySingleton which is never assigned a value should never be referenced and should be deleted.
public GetSingletonInstance(OurSingleton ourSingleton){
singleton = ourSingleton;
}
=>
public GetSingletonInstance(){
singleton = OurSingleton.getInstance();
}
The access to OurSingleton.getInstanceCounter (static member) via OurSingleton.getCounter () (static member function) is not synchronized. That is the only thing that matters. The remainder of your program is simply complicating things. Note that in main you are via mySingleton.getCounter () calling a static function on a null pointer! mySingleton never has another value than null.
You should use enum to implement the singleton pattern, or at least use only one static variable, namely the one holding the singleton object.

Singleton & Multithreading in Java

What is the preferred way to work with Singleton class in multithreaded environment?
Suppose if I have 3 threads, and all of them try to access getInstance() method of singleton class at the same time -
What would happen if no synchronization is maintained?
Is it good practice to use synchronized getInstance() method or use synchronized block inside getInstance().
Please advise if there is any other way out.
If you're talking about threadsafe, lazy initialization of the singleton, here is a cool code pattern to use that accomplishes 100% threadsafe lazy initialization without any synchronization code:
public class MySingleton {
private static class MyWrapper {
static MySingleton INSTANCE = new MySingleton();
}
private MySingleton () {}
public static MySingleton getInstance() {
return MyWrapper.INSTANCE;
}
}
This will instantiate the singleton only when getInstance() is called, and it's 100% threadsafe! It's a classic.
It works because the class loader has its own synchronization for handling static initialization of classes: You are guaranteed that all static initialization has completed before the class is used, and in this code the class is only used within the getInstance() method, so that's when the class loaded loads the inner class.
As an aside, I look forward to the day when a #Singleton annotation exists that handles such issues.
Edited:
A particular disbeliever has claimed that the wrapper class "does nothing". Here is proof that it does matter, albeit under special circumstances.
The basic difference is that with the wrapper class version, the singleton instance is created when the wrapper class is loaded, which when the first call the getInstance() is made, but with the non-wrapped version - ie a simple static initialization - the instance is created when the main class is loaded.
If you have only simple invocation of the getInstance() method, then there is almost no difference - the difference would be that all other sttic initialization would have completed before the instance is created when using the wrapped version, but this is easily dealt with by simply having the static instance variable listed last in the source.
However, if you are loading the class by name, the story is quite different. Invoking Class.forName(className) on a class cuasing static initialization to occur, so if the singleton class to be used is a property of your server, with the simple version the static instance will be created when Class.forName() is called, not when getInstance() is called. I admit this is a little contrived, as you need to use reflection to get the instance, but nevertheless here's some complete working code that demonstrates my contention (each of the following classes is a top-level class):
public abstract class BaseSingleton {
private long createdAt = System.currentTimeMillis();
public String toString() {
return getClass().getSimpleName() + " was created " + (System.currentTimeMillis() - createdAt) + " ms ago";
}
}
public class EagerSingleton extends BaseSingleton {
private static final EagerSingleton INSTANCE = new EagerSingleton();
public static EagerSingleton getInstance() {
return INSTANCE;
}
}
public class LazySingleton extends BaseSingleton {
private static class Loader {
static final LazySingleton INSTANCE = new LazySingleton();
}
public static LazySingleton getInstance() {
return Loader.INSTANCE;
}
}
And the main:
public static void main(String[] args) throws Exception {
// Load the class - assume the name comes from a system property etc
Class<? extends BaseSingleton> lazyClazz = (Class<? extends BaseSingleton>) Class.forName("com.mypackage.LazySingleton");
Class<? extends BaseSingleton> eagerClazz = (Class<? extends BaseSingleton>) Class.forName("com.mypackage.EagerSingleton");
Thread.sleep(1000); // Introduce some delay between loading class and calling getInstance()
// Invoke the getInstace method on the class
BaseSingleton lazySingleton = (BaseSingleton) lazyClazz.getMethod("getInstance").invoke(lazyClazz);
BaseSingleton eagerSingleton = (BaseSingleton) eagerClazz.getMethod("getInstance").invoke(eagerClazz);
System.out.println(lazySingleton);
System.out.println(eagerSingleton);
}
Output:
LazySingleton was created 0 ms ago
EagerSingleton was created 1001 ms ago
As you can see, the non-wrapped, simple implementation is created when Class.forName() is called, which may be before the static initialization is ready to be executed.
The task is non-trivial in theory, given that you want to make it truly thread safe.
A very nice paper on the matter is found # IBM
Just getting the singleton does not need any sync, since it's just a read. So, just synchronize the setting of the Sync would do. Unless two treads try to create the singleton at start up at the same time, then you need to make sure check if the instance is set twice (one outside and one inside the sync) to avoid resetting the instance in a worst case scenario.
Then you might need to take into account how JIT (Just-in-time) compilers handle out-of-order writes. This code will be somewhat near the solution, although won't be 100% thread safe anyway:
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
Singleton inst = instance;
if (inst == null) {
synchronized(Singleton.class) {
instance = new Singleton();
}
}
}
}
return instance;
}
So, you should perhaps resort to something less lazy:
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
Or, a bit more bloated, but a more flexible way is to avoid using static singletons and use an injection framework such as Spring to manage instantiation of "singleton-ish" objects (and you can configure lazy initialization).
You need synchronization inside getInstance only if you initialize your singleton lazily. If you could create an instance before the threads are started, you can drop synchronization in the getter, because the reference becomes immutable. Of course if the singleton object itself is mutable, you would need to synchronize its methods which access information that can be changed concurrently.
This question really depends on how and when your instance is created. If your getInstance method lazily initializes:
if(instance == null){
instance = new Instance();
}
return instance
Then you must synchronize or you could end up with multiple instances. This problem is usually treated in talks on Double Checked Locking.
Otherwise if you create a static instance up front
private static Instance INSTANCE = new Instance();
then no synchronization of the getInstance() method is necessary.
The best way as described in effective java is:
public class Singelton {
private static final Singelton singleObject = new Singelton();
public Singelton getInstance(){
return singleObject;
}
}
No need of synchronization.
Nobody uses Enums as suggested in Effective Java?
If you are sure that your java runtime is using the new JMM (Java memory model, probably newer than 5.0), double check lock is just fine, but add a volatile in front of instance. Otherwise, you'd better use static internal class as Bohemian said, or Enum in 'Effective Java' as Florian Salihovic said.
For simplicity, I think using enum class is a better way. We don't need to do any synchronization. Java by construct, always ensure that there is only one constant created, no matter how many threads are trying to access it.
FYI, In some case you need to swap out singleton with other implementation. Then we need to modify class, which is violation of Open Close principal.Problem with singleton is, you can't extend the class because of having private constructor. So, it's a better practice that client is talking via interface.
Implementation of Singleton with enum class and Interface:
Client.java
public class Client{
public static void main(String args[]){
SingletonIface instance = EnumSingleton.INSTANCE;
instance.operationOnInstance("1");
}
}
SingletonIface.java
public interface SingletonIface {
public void operationOnInstance(String newState);
}
EnumSingleton.java
public enum EnumSingleton implements SingletonIface{
INSTANCE;
#Override
public void operationOnInstance(String newState) {
System.out.println("I am Enum based Singleton");
}
}
The Answer is already accepted here, But i would like to share the test to answer your 1st question.
What would happen if no synchronization is maintained?
Here is the SingletonTest class which will be completely disaster when you run in multi Threaded Environment.
/**
* #author MILAN
*/
public class SingletonTest
{
private static final int PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors();
private static final Thread[] THREADS = new Thread[PROCESSOR_COUNT];
private static int instancesCount = 0;
private static SingletonTest instance = null;
/**
* private constructor to prevent Creation of Object from Outside of the
* This class.
*/
private SingletonTest()
{
}
/**
* return the instance only if it does not exist
*/
public static SingletonTest getInstance()
{
if (instance == null)
{
instancesCount++;
instance = new SingletonTest();
}
return instance;
}
/**
* reset instancesCount and instance.
*/
private static void reset()
{
instancesCount = 0;
instance = null;
}
/**
* validate system to run the test
*/
private static void validate()
{
if (SingletonTest.PROCESSOR_COUNT < 2)
{
System.out.print("PROCESSOR_COUNT Must be >= 2 to Run the test.");
System.exit(0);
}
}
public static void main(String... args)
{
validate();
System.out.printf("Summary :: PROCESSOR_COUNT %s, Running Test with %s of Threads. %n", PROCESSOR_COUNT, PROCESSOR_COUNT);
long currentMili = System.currentTimeMillis();
int testCount = 0;
do
{
reset();
for (int i = 0; i < PROCESSOR_COUNT; i++)
THREADS[i] = new Thread(SingletonTest::getInstance);
for (int i = 0; i < PROCESSOR_COUNT; i++)
THREADS[i].start();
for (int i = 0; i < PROCESSOR_COUNT; i++)
try
{
THREADS[i].join();
}
catch (InterruptedException e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
testCount++;
}
while (instancesCount <= 1 && testCount < Integer.MAX_VALUE);
System.out.printf("Singleton Pattern is broken after %d try. %nNumber of instances count is %d. %nTest duration %dms", testCount, instancesCount, System.currentTimeMillis() - currentMili);
}
}
Output of the program is clearly shows that you need handle this using getInstance as synchronized or add synchronized lock enclosing new SingletonTest.
Summary :: PROCESSOR_COUNT 32, Running Test with 32 of Threads.
Singleton Pattern is broken after 133 try.
Number of instance count is 30.
Test duration 500ms

Categories

Resources