I was going through this tutorial. I understood the volatile keyword usage. But when i tried to achieve same result without using volatile keyword with doing operation on the concern variable with in synchronized block, it is not working. It throws IllegalMonitorStateException. Here is the modified code i tried.
public class VolatileTest {
private static Integer MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
#Override
public void run() {
synchronized(MY_INT){
int local_value = MY_INT;
while ( local_value < 5){
if( local_value!= MY_INT){
System.out.format("Got Change for MY_INT : {0}", MY_INT);
local_value= MY_INT;
try {
MY_INT.wait();
} catch (Exception e) { e.printStackTrace(); }}
}
}
}
}
static class ChangeMaker extends Thread{
#Override
public void run() {
synchronized(MY_INT){
int local_value = MY_INT;
while (MY_INT <5){
System.out.format("Incrementing MY_INT to {0}", local_value+1);
MY_INT = ++local_value;
try {
MY_INT.notify();
} catch (Exception e) { e.printStackTrace(); }
}
}
}}}
What I want to know is, in this case is volatile replaceable with synchronized block, if yes then how to do that?
Thanks.
The problem is here:
MY_INT = ++local_value;
MY_INT is an Integer variable, and when you assign a new value to it, the object that you are locking here:
synchronized(MY_INT){
will be different to the object that you are notifying here:
MY_INT.notify();
... and that will lead to the exception.
The solution is to make the lock object static final. Obviously that means you can't assign to it ... but that is the whole point!
Related
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.
In the following program, does the this keywords in the LoggerThread class refer to LoggerThread object or LogService object? Logically it should refer to LogService in order for the syncronization to work, but semantically it seems it is referring to LoggerThread.
public class LogService {
private final BlockingQueue<String> queue;
private final LoggerThread loggerThread;
private final PrintWriter writer;
#GuardedBy("this") private boolean isShutdown;
#GuardedBy("this") private int reservations;
public void start() { loggerThread.start(); }
public void stop() {
synchronized (this) { isShutdown = true; }
loggerThread.interrupt();
}
public void log(String msg) throws InterruptedException {
synchronized (this) {
if (isShutdown)
throw new IllegalStateException("...");
++reservations;
}
queue.put(msg);
}
private class LoggerThread extends Thread {
public void run() {
try {
while (true) {
try {
synchronized (this) {
if (isShutdown && reservations == 0)
break;
}
String msg = queue.take();
synchronized (this) { --reservations; }
writer.println(msg);
} catch (InterruptedException e) { /* retry */ }
}
} finally {
writer.close();
}
}
}
}
Thank you for your help
this within LoggerThread methods refers to a LoggerThread instance.
LogService.this refers to the outer class.
Both isShutdown and reservations are synchronised by the different locks (LoggerThread.this and LogService.this), so #GuardedBy("this") doesn't reflect the reality.
This code is from the great book "Java Concurrency In Practice", Listing 7.15
It is a typo and is mentioned in "Errata" section:
http://jcip.net.s3-website-us-east-1.amazonaws.com/errata.html
this refers to the current instance of the immediately enclosing class. JLS #15.8.4.
Logically it should refer to LogService in order for the syncronization to work, but semantically it seems it is referring to LoggerThread.
Correct. It's a bug.
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.
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());
}
}
I am very new to threads. I wrote a code and expected my output as 20000 consistently. But that's not the case. Please find the code below:
class Runner4 implements Runnable {
static int count = 0;
public synchronized void increase() {
count++;
}
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
increase();
}
}
}
public class threading4 {
public static void main(String[] args) {
Thread t1 = new Thread(new Runner4());
t1.start();
Thread t2 = new Thread(new Runner4());
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Runner4.count);
}
}
Any explanation?
Thanks!!
You are synchronizing on two different objects in your code (corresponding to the two objects you created). As such, there is no protection of the shared static variable, and you get unpredictable results. Basically, there is no effective synchronization going on in your program. You can fix this with a simple modification.
Change:
public synchronized void increase(){
count++;
}
To:
public void increase(){
synchronized(Runner4.class) {
count++;
}
}
Note that I am not saying this is the best way to accomplish this kind of synchronization - but the important take-away is that, if you are modifying a class level variable, you need class level synchronization as well.
Your code would work if count was not static.
public synchronized void increase() {
// method body
}
is equivalent to
public void increase() {
synchronized(this) {
// method body
}
}
Since count is static, both t1 and t2 are accessing it with different locks, resulting in non-deterministic behavior. Either make Runner4.increase synchronize on a common lock (Runner4.class or a private static lock object would work just fine), or make count non-static.
The way you're trying to achieve what you want is is not really the best way.
A better way to do it is define a class called Counter, as the following:
public class Counter
{
int count;
public Counter()
{
count = 0;
}
public synchronized void increase() {
count++;
}
public int getCount()
{
return count;
}
}
The class has the methods of increasing the counter and getting it.
What you need to do now is have a Counter object to be shared by two threads that call the increase() method. So your thread class would look like this:
class Runner4 extends Thread {
Counter count;
public Runner4(Counter c)
{
count = c;
}
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
count.increase();
}
}
}
Notice that the class takes a Counter object and calls the increase method. Also the class extends Thread instead of implementing Runnable. There is really no much difference, it's just now your Runner4 can use Thread class methods.
From your main defines a Counter object and two Runner4 threads, and then pass the Counter object to each one of them:
public static void main(String[] args) {
Counter count = new Counter();
Thread t1 = new Runner4(count);
t1.start();
Thread t2 = new Runner4(count);
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(count.getCount());
}