why DCL use volatile ,not use final?i code run same effect - java

package test1;
import java.util.Random;
public class OneInstanceService {
// use volatile or final,them has same effect,
// but difference volatile or final in DCL demo?
public int i_am_has_state;
private static OneInstanceService test;
private OneInstanceService() {
i_am_has_state = new Random().nextInt(200) + 1;
}
public static OneInstanceService getTest1() {
if (test == null) {
synchronized (OneInstanceService.class) {
if (test == null) {
test = new OneInstanceService();
}
}
}
return test;
}
public static void reset() {
test = null;
}
}
//----------------------------------------
package test1;
import java.util.concurrent.CountDownLatch;
public class Test1 {
public static void main(String[] args) throws InterruptedException {
for (;;) {
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
Thread t1 = new Thread() {
#Override
public void run() {
try {
latch.await();
OneInstanceService one = OneInstanceService.getTest1();
if (one.i_am_has_state == 0) {
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
}
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
}
latch.countDown();
end.await();
OneInstanceService.reset();
}
}
}
only use :
public int i_am_has_state;
run result is :
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
but modify code bottom:
volatile public int i_am_has_state;
or
final public int i_am_has_state;
no run bottom code:
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
i question is :
DCL use final ok
DCL use final volatile ok
so
in DCL final and volatile difference?
thank you very much !

final and volatile cannot go together because they are purposefully opposite.
either you have a static field initialized once upon class init:
static final Object x;
static {
x = ...
}
or you have a volatile static field that multiple thread can race to set (your case).
It must be volatile for the double check idiom to work (with the new volatile semantic since jdk 1.5). Since then, the volatile has memory barriers preventing reordering of instructions involving other variables, which somehow (I can't recall that stuff now...) makes the ugly DCL work again... but doesn't make it less ugly.
(I never needed to use the DCL; without DCL, synchronization is still essentially uncontended because the if(x==null) is so fast.)

thank all, bottom not answer.
I modify code:
package test1;
import java.util.Random;
public class OneInstanceService {
final public int i_am_has_state;
volatile private static OneInstanceService test;
private OneInstanceService() {
i_am_has_state = new Random().nextInt(200) + 1;
}
public static OneInstanceService getTest1() {
if (test == null) {
synchronized (OneInstanceService.class) {
if (test == null) {
test = new OneInstanceService();
}
}
}
return test;
}
public static void reset() {
test = null;
}
}
Just had a sudden inspiration, the code is so perfect? I think I'm really getting mixed up.
shmosel:Forgive me for not formatting code and hightline, thank you very much.

Related

Threading, volatile variable not updagting

I looked around and seemed similar code but mine is not working. My volatile variable is chaning in the class clock but my class vistor is not getting the changed variable. I will post my code. If theres a similar queston please link. Thank you for the help.
I tried by setting the declarations in all my classes for the volatile boolean variables to false. It didn't help.
public class Main {
volatile static boolean isInSession;
volatile static boolean sessionOver;
public static void main (String [] args)
{
for (int i = 0; i < 25; i++) {
Visitor visitor = new Visitor(i, isInSession);
visitor.start();
}
Thread clock = new Thread(new Clock(isInSession, sessionOver));
clock.start();
}
}
public class Visitor extends Thread {
volatile static boolean isInSession;
private int visitorId;
volatile static int seats = 5;
Visitor(int visotrId, boolean isInSession)
{
this.isInSession = isInSession;
setName("visitorId " + visitorId);
}
#Override
public void run() {
while(true)
{
while(isInSession){}
System.out.println("In visitor isInSession " + isInSession);
if(isInSession)
System.out.println("Visitor isInSession " + isInSession);
try {
Thread.currentThread().sleep(5000);
}
catch(InterruptedException e)
{ }
}
}
public void msg(String m) {
System.out.println("["+(System.currentTimeMillis()-time)+"]
"+getName()+": "+m);
}
}
public class Clock implements Runnable {
volatile static boolean isInSession;
volatile static boolean sessionOver;
private int session = 0;
public Clock(boolean isInSession, boolean sessionOver)
{
this.isInSession = isInSession;
this.sessionOver = sessionOver;
}
#Override
public void run() {
while(true)
{
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
}
isInSession = false;
msg("Theater is open");
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
}
isInSession = true;
//System.out.println("In clock isInSession " + isInSession);
session++;
}
}// end of run
public void msg(String m) {
System.out.println("["+(System.currentTimeMillis()-time)+"]" +"Clock:
"+ m);
}
}
You can use AtomicBoolean for your purpose.
As JB Nizet has pointed out, arguments in Java are passed-by-value. Here's an answer on another SO post that explains this in detail.
For your purpose, it suffices to know that, "when we pass the value of an object, we are passing the reference to it" (a quote from the SO post mentioned above). By creating an AtomicBoolean object and passing it to both the Clock and Visitor objects, when Clock updates the value of the AtomicBoolean, the Visitor objects will receive the updated value too.
So, your main class should look like this:
public class Main {
static AtomicBoolean isInSession = new AtomicBoolean(); // default value is false
static AtomicBoolean sessionOver = new AtomicBoolean();
public static void main (String [] args)
{
for (int i = 0; i < 25; i++) {
Visitor visitor = new Visitor(i, isInSession);
visitor.start();
}
Thread clock = new Thread(new Clock(isInSession, sessionOver));
clock.start();
}
}
To access the value of the AtomicBoolean in Visitor or to update the value in Clock, you can use the get() and set(boolean) method respectively.

Value gets overwritten in Runnable class - Java

I am facing a problem with a Runnable class. The value that is passed to the runnable class is overwritten by the last value it received when the same value is passed to another class.
The function of the runnable class is to pass the values to another function in another class to print them. But only the last value received by the Runnable class is printed.
Here is my code,
This is the main class from where the values are passed.
public class MainClass {
private int intVal = -1;
public void MainMethod() {
ExecutorUtil theExecutor = ExecutorUtil.GetInstance();
for(int i = 0; i < 3; i++) {
intVal = i;
synchronized (this) {
theExecutor.SubmitTask(new ActionExecutor(intVal));
}
}
}
}
This is the executorUtil that I use to call the thread.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.BlockingQueue;
public class ExecutorUtil {
private static ExecutorUtil theInstance;
private ExecutorService theExecutor;
private BlockingQueue<Runnable> theQueue;
protected ExecutorUtil() {
theExecutor = CreateThreadPoolExecutor();
}
private ExecutorService CreateThreadPoolExecutor() {
theQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 900, java.util.concurrent.TimeUnit.SECONDS, theQueue);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
public static ExecutorUtil GetInstance() {
if (theInstance == null) {
synchronized(ExecutorUtil.class) {
if (theInstance == null) {
theInstance = new ExecutorUtil();
}
}
}
return theInstance;
}
public void SubmitTask(Runnable runnable) {
theExecutor.submit(runnable);
}
}
This is the thread that passes the received value to the function that prints these values.
public class ActionExecutor implements Runnable {
int iVal = -1;
public ActionExecutor(int iVal) {
this.iVal = iVal;
}
public void run() {
SecondClass sc = new SecondClass();
sc.printIntVal(iVal);
}
}
And this is the class that prints the values.
public class SecondClass {
public void printIntVal(int i) {
System.out.println(i);
}
}
Expected Output:
0
1
2
Obtained Output:
2
2
2
No idea why this is behaving in this way!
UPDATE:
The issue occurs only when a non-primitive data type is used. In my example here, I've used an integer value (intVal). Since java passes the value for primitive data types, the output was obtained as expected. But in my original code, I've used a JSONObject. And since java passes the reference of the object for non-primitive data types, the value was over-written.
I have solved this by creating new JSONObject for each iteration.
It seems that somewhere you have static field, which store your number.
So, I suppose, that you have 3 instances of ActionExecutor, but it looks like field has static modifier, so each of this instance will have latest value.
Check this case...
So after I read your question and studied your code I might as well try it out. And lo and behold it's working as expected. The only difference here is that there is a race condition so the output my vary in order, but it will not print the same numbers.
Output might
1st: 0 1 2
2nd: 0 1 2
3rd: 2 1 0
Here is the full code to try it out:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
public class MainClass {
private int intVal = -1;
public void MainMethod() {
ExecutorUtil theExecutor = ExecutorUtil.GetInstance();
for(int i = 0; i < 3; i++) {
intVal = i;
synchronized (this) {
theExecutor.SubmitTask(new ActionExecutor(intVal));
}
}
}
public class ActionExecutor implements Runnable {
int iVal = -1;
public ActionExecutor(int iVal) {
this.iVal = iVal;
}
public void run() {
SecondClass sc = new SecondClass();
sc.printIntVal(iVal);
}
}
public class SecondClass {
public void printIntVal(int i) {
System.out.println(i);
}
}
public static class ExecutorUtil {
private static ExecutorUtil theInstance;
private ExecutorService theExecutor;
private BlockingQueue<Runnable> theQueue;
protected ExecutorUtil() {
theExecutor = CreateThreadPoolExecutor();
}
private ExecutorService CreateThreadPoolExecutor() {
theQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 900, java.util.concurrent.TimeUnit.SECONDS, theQueue);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
public static ExecutorUtil GetInstance() {
if (theInstance == null) {
synchronized(ExecutorUtil.class) {
if (theInstance == null) {
theInstance = new ExecutorUtil();
}
}
}
return theInstance;
}
public void SubmitTask(Runnable runnable) {
theExecutor.submit(runnable);
}
}
public static void main(String[] args) {
MainClass main = new MainClass();
main.MainMethod();
}
}
You might want to clean and rebuild your project. Otherwise it's working..

Java volatile keyword behaviour changes due to remove local variable

From the link, it provide a demo of the java keyword 'volatile'. The demo code works fine. But I try to do a little modification. the behaviour is defferent.
My code :
public class VolatileTest4 {
private static int MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
#Override
public void run() {
while (MY_INT < 5) {
System.out.println("Got Change for MY_INT : " + MY_INT);
}
}
}
static class ChangeMaker extends Thread {
#Override
public void run() {
while (MY_INT < 5) {
System.out.println("Incrementing MY_INT to " + MY_INT);
MY_INT++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
What I do is just remove the local variable of local_value.
The post says 'Without the volatile keyword, the change listener loop infinitely'.
But My code is Without the volatile keyword, the change listener ends normally.
What is the defference? what cause the change listener end?
I've compared the code you've provided to the code in the article and there are substantive differences. Having modified and run the code from the article in the manner described by the author, I was able to replicate his results. My code is as follows:
public class VolatileTest {
private static int MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
#Override
public void run() {
int local_value = MY_INT;
while ( local_value < 5){
if( local_value!= MY_INT){
System.out.println(String.format("Got Change for MY_INT : %S", MY_INT));
local_value= MY_INT;
}
}
}
}
static class ChangeMaker extends Thread{
#Override
public void run() {
int local_value = MY_INT;
while (MY_INT <5){
System.out.println(String.format("Incrementing MY_INT to %S", local_value+1));
MY_INT = ++local_value;
try {
Thread.sleep(500);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
}
The volatile keyword changes a variable's visibility semantics. Changes to a member marked volatile become visible to all threads after the write operation completes. However, the absence of volatile doesn't mean that the changes won't be visible. volatile provides some certainty around visibility; without it, you can't be sure when changes made to a value will become visible in other threads, if ever.
The author is trying to make the point that because the variable is not marked volatile the changes made by the ChangeMaker are not visible to the ChangeReader and in turn, the ChangeListener never terminates. See this article for a better treatment of the volatile keyword.

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;
}

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());
}
}

Categories

Resources