Calling static method by reflection is thread safe in java? - java

Is this code thread safe ?
create runnable and invoke a method by reflection :
public class A {
public static void someMethod (List<VO> voList){
int endIndex=0;
for (int firstIndex = 0; firstIndex < voList.size(); ) {
endIndex = Math.min(firstIndex + threadSize, voList.size());
Runner runner = null;
try {
runner = new Runner(voList.subList(firstIndex, endIndex),
B.class.getMethod("createSomeString", D.class));
} catch (NoSuchMethodException ex) {
log.warn(ex.getMessage());
}
//start a thread
runner.start();
}
}
private static class Runner extends Thread {
private Method method;
private List<C> list;
public Runner(Method method,List<C> clist) {
this.method = method;
this.list=clist;
}
}
public void run() {
for (C vo: list) {
String xml = (String) method.invoke(null,vo);
}
}
}
I want to call a static method by reflection ,is this code block thread safe ?
public class B {
public static String createSomeString(D a) throws Exception {
return a.name;
}
}
and D.class is Plain old java object class like this :
public class D implements Serializable{
private String name;
}

If you're using static variables inside the method, or anything else that needs to be thread safe, the synchronized keyword is one option.
public class B {
public synchronized String createSomeString(A a) throws Exception {
return a.name;
}
}
Another option would be to use a queue with a pool size of one. Google has a good example project available for this available at: Running Code on a Thread Pool Thread
If it's a.name that may be accessed by multiple threads then you'll want to synchronize that instead.
public class B {
public static String createSomeString(A a) throws Exception {
String strName = "";
synchronize (a.name) {
strName = new String(a.name);
}
return strName;
}
}

You only doing read operation in your static method, so it's thread safe no matter how much concurrent your program is. if both read and write involved, then you have to synchronize your static method or code block.

Use volatile. Please click here to know about http://javarevisited.blogspot.in/2011/06/volatile-keyword-java-example-tutorial.html

Related

How to create a thread synhronization a method that can be executed by N threads?

I whould like to block a method execution from more thab 3 threads. The method can be executed recursively. I have following agly code. Can I achive this by using better way?
private static class MyHolder {
private static Semaphore limitThreadsSemaphore = new Semaphore(3);
private static Set<Thread> asquiredThreads = new HashSet<Thread>();
}
#Override
public void someMethod() {
if (!MyHolder.asquiredThreads.contains(Thread.currentThread())) {
synchronized (MyHolder.asquiredThreads) {
if (!MyHolder.asquiredThreads.contains(Thread.currentThread())) {
try {
MyHolder.limitThreadsSemaphore.acquire();
MyHolder.asquiredThreads.add(Thread.currentThread());
} finally {
MyHolder.limitThreadsSemaphore.release();
MyHolder.asquiredThreads.remove(Thread.currentThread());
}
}
}
}
return super.someMethod();
}
Thanks.
The simplest approach would be to refactor the recursive method to be private and then have the public method unconditionally acquire the semaphore, call the private method and then release the semaphore again. The recursive calls route straight to the private method so don't go through the semaphore guard code.
If that is not an option then the simplest approach I can think of would be to use a ThreadLocal flag
ThreadLocal<Object> alreadyIn = new ThreadLocal<>();
public void someMethod() {
boolean needSem = (alreadyIn.get() == null);
if(needSem) {
semaphore.acquire();
alreadyIn.set(new Object());
}
try {
// do stuff
} finally {
if(needSem) {
alreadyIn.remove();
semaphore.release();
}
}
}
I guess "someMethod" is the method you want to block execution,yeah?. Why don'y you do this? :
private static class MyHolder {
private static Semaphore limitThreadsSemaphore = new Semaphore(3);
public boolean semaphoreAdquired = false; //Make it private
public Semaphore getSemaphore()
{
return limitThreadsSemaphore;
}
}
#Override
public void someMethod() {
boolean ReleaseSemaphore = false;
if(!semaphoreAdquired)
{
MyHolder.getSemaphore().acquire();
semaphoreAdquired = true;
ReleaseSemaphore = true;
}
super.someMethod();
if(ReleaseSemaphore)
{
MyHolder.getSemaphore().release();
semaphoreAdquired = false;
}
}
Based on the documentation for Semaphor, this should be achievable using only acquire() and release() around the critical section. Also, you should be able to put the semaphor in the current class, no need for a separate class to contain the Semaphor.
private static Semaphore limitThreadsSemaphore = new Semaphore(3);
#Override
public void someMethod() {
limitThreadsSemaphore.acquire();
// do work.
limitThreadsSemaphore.release();
}
Update: If you need to call a method recursively within a thread, then the easiest way is to use a helper method to acquire the semaphor, and then invoke the recursive method from that helper method after acquiring the sempahor. You would call the helper instead of the original method in all the initial calls.
private static Semaphore limitThreadsSemaphore = new Semaphore(3);
public void someMethodHelper() {
limitThreadsSemaphore.acquire();
someMethod();
limitThreadsSemaphore.release();
}
#Override
public void someMethod() {
// do work, with recursive calls.
}

static volatile boolean - thread not getting terminated

I wrote simple multithreaded application, just to play around with concurrency but I have a problem with boolean variable which controles the loop in thread. One of the functions should stop the thread if there's noelements left in queue and I guess that is my problem because If I add something in between braces to:
while (!queue.isEmpty()) {
}
isRunning = false;
So it becomes :
while (!queue.isEmpty()) {
System.out.println("ASD");
}
isRunning = false;
It is working a bit better - the program terminates after executing turnOff method
Any Ideas?
Here is full code of my app:
package test;
public class xxx {
public static void main(String[] args) {
Foo instance = Foo.getInstance();
Thread x = new Thread(instance);
x.start();
for (int count = 1; count < 100000; count++)
instance.addToQueue(count + "");
instance.turnOff();
}
}
And:
package test;
import java.util.LinkedList;
import java.util.List;
public class Foo implements Runnable {
private static Foo inner = null;
private static List<String> queue = new LinkedList<String>();
private volatile static boolean isRunning = false;
private Foo() { }
public static Foo getInstance() {
if (inner == null) {
inner = new Foo();
}
return inner;
}
public void addToQueue(String toPrint) {
synchronized (queue) {
queue.add(toPrint);
}
}
public void removeFromQueue(String toRemove) {
synchronized (queue) {
queue.remove(toRemove);
}
}
public void turnOff() {
while (!queue.isEmpty()) {
}
System.out.println("end");
isRunning = false;
}
#Override
public void run() {
isRunning = true;
while (isRunning) {
if (!queue.isEmpty()) {
String string = queue.get(0);
System.out.println(string);
removeFromQueue(string);
}
}
}
}
It is a race condition problem. Possibly the run method (the other thread) is executed after the turnOff in in the main thread so the flag isRunning is set as true again and the loop never ends.
That would explain why with a simple System.out.println("ASD") becomes better: the isRunning=false is delayed.
You have lots of problems in your code.
Busy loops in turnOff and wait
Unsynchronized access to queue in turnOff and run
Non-volatile, non-final access to inner
Needlessly static isRunning and queue variables
Race condition between turnOff and start invocations
Some of these are harmless in this specific instance (e.g. instance is always accessed from the main thread), but depending on your hardware configuration you are going to get bitten by some combination of the rest of them. The reason that adding the System.out "fixes" the problem is that it renders one of the busy loops less busy (fixes 1) and has an internal synchronization mechanism (fixes 2), but the others are still there.
I suggest getting rid of the isRunning variable and the test for queue.isEmpty() and replacing with a CountDownLatch.
package test;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class Foo implements Runnable {
private static final Foo inner = new Foo();
private final List<String> queue = new LinkedList<String>();
private final CountDownLatch latch = new CountDownLatch(1);
private Foo() { }
public static Foo getInstance() {
return inner;
}
public void addToQueue(String toPrint) {
synchronized (queue) {
queue.add(toPrint);
}
}
public void removeFromQueue(String toRemove) {
synchronized (queue) {
queue.remove(toRemove);
}
}
public boolean isEmpty() {
synchronized (queue) {
return queue.isEmpty();
}
}
public String getHead() {
synchronized (queue) {
return queue.get(0);
}
}
public void turnOff() throws InterruptedException {
latch.await();
System.out.println("end");
}
#Override
public void run() {
while (!isEmpty()) {
String string = getHead();
System.out.println(string);
removeFromQueue(string);
}
latch.countDown();
}
}
And the runner
package test;
public class XXX {
public static void main(String[] args) throws InterruptedException {
Foo instance = Foo.getInstance();
Thread x = new Thread(instance);
for (int count = 1; count < 100000; count++)
instance.addToQueue(count + "");
x.start();
instance.turnOff();
}
}
The main problem is the race condition between adding/removing elements and checking whether the queue is empty. In more words:
Wrapping add and remove calls in synchronized block provides you guarantees that all invocations of these methods will be performed sequentially. But, there is one more access to queue variable outside of synchronized block - it is queue.isEmpty(). It means there is a chance that some thread will get the result of this call and while it performs actions inside if block, other thread may add or remove elements.
This code also has some more concurrency problems, please let me know if you want them to be discussed (they are a little bit offtopic).
As Germann Arlington point, the value of queue.isEmpty() seems to be cached in the main thread. Try synchronize it:
while (true) {
synchronized(queue) {
if(queue.isEmpty())
break;
}
}
Or just make the queue to be volatile:
private volatile static List<String> queue = new LinkedList<String>();
This will solve your problem.
Use volatile variable isRunning in turnOff() method's while loop also.
public void turnOff() {
while (isRunning && !queue.isEmpty()) {
}
System.out.println("end");
isRunning = false;
}

Case Study: Singleton class inheritance - Good or bad?

I have an example code of Singleton class inheritance below. However, I've not forseen if there's any hidden issue might happen with this code. Can someone analyze and give me a hint?
interface ChairIF {
public int getLeg();
public void test();
}
class ChairImpl implements ChairIF {
private static final Lock lock = new ReentrantLock();
private static ChairIF instance = null;
public static ChairIF getInstance(String clazzName) {
//get class by clazzName
Class clazz = null;
try {
clazz = Class.forName(clazzName);
} catch (ClassNotFoundException ex) {
lock.lock();
try {
if (instance == null) {
instance = new ChairImpl();
}
} finally {
lock.unlock();
}
}
//init singleton instance of clazzName
if (instance == null) {
lock.lock();
try {
if (instance == null) {
instance = (ChairIF) clazz.newInstance();
} else {
if (instance.getClass() != clazz) {
instance = (ChairIF) clazz.newInstance();
}
}
} catch (Exception ex) {
instance = new ChairImpl();
} finally {
lock.unlock();
}
} else {
lock.lock();
try {
if (!instance.getClass().getName().equals(clazz.getName())) {
instance = (ChairIF) clazz.newInstance();
}
} catch (Exception ex) {
instance = new ChairImpl();
} finally {
lock.unlock();
}
}
return instance;
}
public int getLeg() {
return 4;
}
public void test() {
throw new UnsupportedOperationException();
}
}
class ThreeLegChair extends ChairImpl {
public ThreeLegChair() {}
public int getLeg() {
return 3;
}
public void test() {
int i = 0;
while(i < 10000) {
System.out.println("i: " + i++);
}
}
}
class NoLegChair extends ChairImpl {
public NoLegChair() {}
public int getLeg() {
return 0;
}
public void test() {
int j = 0;
while(j < 5000) {
System.out.println("j: " + j++);
}
}
}
public class Test {
public static void main(String[] args) {
System.out.println(ChairImpl.getInstance("ThreeLegChair").getLeg());
System.out.println(ChairImpl.getInstance("NoLegChair").getLeg());
/***
TODO: build logic to run 2 test() simultaneously.
ChairImpl.getInstance("ThreeLegChair").test();
ChairImpl.getInstance("NoLegChair").test();
****/
}
}
As you can see, I did put some test code in 2 subclasses. ThreeLegChair is to loop from 0 to 10000 and print it out. NoLegChair is to loop only from 0 to 5000 and print it out.
The result I got in the console log is correct. ThreeLegChair printed i from 0 to 10000. NoLegChair printed j from 0 to 5000.
Please share me your thought :)
Singleton pattern is achieved using the concept of private constructor i.e. the class itself is responsible for creating single instance of the class (singleton) and preventing other classes from creating objects.
Now as the constructor is private, you cannot inherit the singleton class at first place. In your case, I do not see a private constructor which makes it vulnerable to object creation from other classes accessing it.
Singleton pattern examples:
Using enumerations in Java
enum SingletonEnum {
SINGLE_INSTANCE;
public void doStuff() {
System.out.println("Singleton using Enum");
}
}
Lazy initialization approach
class SingletonClass {
private static SingletonClass singleInstance;
private SingletonClass() {
// deny access to other classes
}
// The object creation will be delayed until getInstance method is called.
public static SingletonClass getInstance() {
if (null == singleInstance) {
// Create only once
singleInstance = new SingletonClass();
}
return singleInstance;
}
}
However, the above example may not guarantee singleton behavior in multithreaded environment. It is recommended to use double checked locking mechanism to ensure that you have created a single instance of this class.
The code you post isn't an implementation of the singleton pattern.
Quite simply, you can do:
ChairImpl ci = new ChairImpl();
And instantiate as many as you want.
The traditional method of implementing the singleton pattern is the make the constructor private, have a private static field that holds the single instance of the class, and a static getInstance() method that either instantiates that instance or returns the existing one. Making that threadsafe involves either declaring it synchronized or using a locking scheme.
The private constructor bit makes it so you can't inherit from it.
That said, in Java the preferred way is using an enum which provides all the hard parts for free:
public enum MySingleton {
INSTANCE;
public int getLeg() {
return 4;
}
}
And using as:
MySingleton ms = MySingleton.INSTANCE;
int leg = ms.getLeg();
Singletons usually have private constructor. Your class is not following proper Singleton pattern. otherwise you would not be inherit your singleton class.

How can I make a public static unsynchronized getInstance() method return multiple instances of a private static reference variable to an object?

One of the SCJP practice exam questions I ran across supplied the code in the SafeDeposit class. The answer to the question claimed that if another class used multiple threads that it would be possible for the unsynchronized (non thread safe) getInstance() method to return multiple instances of SafeDeposit. I have tried, and tried and cannot get the toString() method to indicate that there is ever more than one SafeDeposit instance created. Am I missing something, or is this just one of those things that "could" happen but is really, really, really unlikely to happen?
class SafeDeposit {
private static SafeDeposit sd;
public static SafeDeposit getInstance() {
if(sd == null) sd = new SafeDeposit();
return sd;
}
private SafeDeposit() { }
}
public class PrivCon {
public static void main(String[] args) {
String checker;
SafeThief wizard = new SafeThief();
SafeThief wizard2 = new SafeThief();
for(int i = 0; i < 10; i ++) {
new Thread(wizard).start();
new Thread(wizard2).start();
}
}
}
class SafeThief implements Runnable {
public void run() {
System.out.println(SafeDeposit.getInstance().toString());
}
}
is this just one of those things that "could" happen but is really, really, really unlikely to happen?
Try this code and see how unlikely it really is:
class SafeDeposit {
private static SafeDeposit sd;
public static SafeDeposit getInstance() {
if(sd == null) sd = new SafeDeposit();
return sd;
}
private SafeDeposit() { }
static void warmup() {
for (int i = 0; i < 100_000; i++) getInstance();
sd = null;
}
}
public class PrivCon {
public static void main(String[] args) {
SafeDeposit.warmup();
SafeThief wizard = new SafeThief();
for(int i = 0; i < 10; i ++) new Thread(wizard).start();
}
}
class SafeThief implements Runnable {
public void run() {
try { Thread.sleep(100); } catch (InterruptedException e) { }
System.out.println(SafeDeposit.getInstance().toString());
}
}
This is my typical output:
test.SafeDeposit#52e5376a
test.SafeDeposit#34780af5
test.SafeDeposit#351775bc
test.SafeDeposit#2b1be57f
test.SafeDeposit#6ae6235d
test.SafeDeposit#6276e1db
test.SafeDeposit#52e5376a
test.SafeDeposit#302b2c81
test.SafeDeposit#60f00e0f
test.SafeDeposit#1732a4df
Hardly any duplicates at all.
If you want to know why, it's because I added warmup code, which caused the getInstance() method to be JIT-compiled into an aggressively optimized piece of code which leverages the liberties given by the Java Memory Model.
I also added some sleep time to the beginning of the Runnable because as soon as one thread writes the value, those threads which start after that point will reliably observe the write. So it is better to first let all threads start, then let them call getInstance.
Correct. This is NOT thread safe,
if(sd == null) // Thread B here <---
sd = new SafeDeposit(); // Thread A here <---
return sd;
So if you have Thread A and B as above you will get two instances of your Singleton instantiated. To see it, add a print method in the constructor like this =
private SafeDeposit() {
System.out.println("In SafeDeposit constructor - Should only print ONCE");
try {
Thread.sleep(2000); // <-- Added to help reproduce multiple
// instances being created.
} catch (Exception e) {
}
}
SafeDeposit constructor is running atomically in your code and you're not seeing the problem. To simulate a more real situation, change SafeDeposit constructor to the code below and you will see the result by yourself.
private SafeDeposit() {
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {}
}
The way to stress a singleton is to use a CountDownLatch to make a horde of threads descend on it all at once. Sadly this code fails to print anything other than 1 but I suspect that is because I am testing it on a one-core laptop. Would someone test it on a multicore CPU and see if it prints anything else?
See comments below for tests results returning result > 1 meaning that more than one instance of the supposed singleton was actually created.
public class Test {
static class SafeDeposit {
private static SafeDeposit sd;
public static SafeDeposit getInstance() {
if (sd == null) {
sd = new SafeDeposit();
}
return sd;
}
private SafeDeposit() {
}
}
static final Set<SafeDeposit> deposits = Collections.newSetFromMap(new ConcurrentHashMap<SafeDeposit,Boolean>());
static class Gun implements Runnable {
private final CountDownLatch wait;
public Gun (CountDownLatch wait) {
this.wait = wait;
}
#Override
public void run() {
try {
// One more thread here and ready.
wait.countDown();
// Wait for the starting pistol.
wait.await();
// Grab an instance - nnnnnnnnow!!!.
SafeDeposit safe = SafeDeposit.getInstance();
// Store it in the Set.
deposits.add(safe);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
// Use that many Threads
private static final int ArmySize = 1000;
public static void main(String[] args) throws InterruptedException {
// The Latch will wait for all threads to be ready.
CountDownLatch latch = new CountDownLatch(ArmySize);
Thread[] threads = new Thread[ArmySize];
for ( int i = 0; i < ArmySize; i++ ) {
// Make all threads and start them.
threads[i] = new Thread(new Gun(latch));
threads[i].start();
}
// Wait for all to complete.
for ( int i = 0; i < ArmySize; i++ ) {
threads[i].join();
}
// How many unique Safes did we et?
System.out.println(deposits.size());
}
}

IlleagalMonitorStateException when I am trying to run this program

public class ThreadTest
{
public static Integer i = new Integer(0);
public static void main(String[] args) throws InterruptedException
{
ThreadTest threadTest = new ThreadTest();
Runnable odd = threadTest.new Numbers(1, "thread1");
Runnable even = threadTest.new Numbers(0, "thread2");
((Thread) odd).start();
((Thread) even).start();
}
class Numbers extends Thread
{
int reminder;
String threadName;
Numbers(int reminder, String threadName)
{
this.reminder = reminder;
this.threadName = threadName;
}
#Override
public void run()
{
while (i < 20)
{
synchronized (i)
{
if (i % 2 == reminder)
{
System.out.println(threadName + " : " + i);
i++;
i.notify();
}
else
{
try
{
i.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
}
You can't synchronize on i because it changes during execution of your program.
Since Integer in Java is immutable, after executing i++ i will contain a reference to another object, not the object you have synchronized on. So, you can't call wait()/notify() on this new object, because these methods may be only called on the object you are synchronized on, otherwise you get IllegalMonitorStateException.
You need to synchronize on some other object that doesn't change during execution. For example, you may create a separate object for this purpose:
public class ThreadTest {
public static Integer i = new Integer(0);
public static Object lock = new Object();
...
class Numbers extends Thread {
...
#Override
public void run() {
...
synchronized (lock) {
...
lock.notify();
...
lock.wait();
...
}
}
}
}
This line:
i++;
is equivalent to:
i = i + 1;
which (due to autoboxing) becomes something like:
i = new Integer(i.intValue() + 1);
So, when you call i.notify() you are synchronized on the old i, not the new one.
I'd suggest changing i into an ordinary int variable, and create a separate object to synchronize on:
static int i = 0;
static Object iMonitor = new Object();
As documentation states the exception is thrown when
the current thread is not the owner of the object's monitor
It also states that
This method should only be called by a thread that is the owner of this object's monitor.
And this condition can be obtained by
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.
You could try calling the wait method from inside the class that uses i. This could be done by extending the class and writing two new methods for notify and wait..
You cannot put wait() and notify() in the same synchronized block because that will just cause a deadlock. Make sure only the wait and notify functions are wrapped with a synchronized block like this:
synchronized (i) {
i.wait(); // or i.notify();
}

Categories

Resources