While loops do not terminate when condition is satisfied - java

To my understanding the following code should terminate normally as the condition stopRunning = true; is met.
However, when I run this program it is printing only Last line of Main(), Start Method ended is never printed as the while loop is never terminated.
public class Test {
private static boolean stopRunning = false;
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
#Override
public void run() {
start();
}
}).start();
Thread.sleep(100);
stopRunning = true;
System.out.println("Last line of Main()");
}
public static void start() {
while (!stopRunning) {
}
System.out.println("Start Method ended.");
}
}
Please help me understand this behavior.

Changing the flag to volatile with
private static volatile boolean stopRunning = false;
will mean that other threads see the change immediately (from main memory instead of a cache), and the code executes as you expect. How volatile relates to Java's memory model is explained further e.g. in this tutorial.

As Mick stated, you should use the volatile keyword to synchronize your variable, so on a change the new value is written directly back to memory and your code will work as expected.
Be aware (also stated in the article Mick linked) that volatile does not guarantee to avoid race conditions, so if two different threads would read your variable, it is not safe that they both read the same value (despite everything is read from memory and on change directly written back)

As stated in previous answers:
Like Mike stated - in run() you should use Test.start() or rename the method. The start you are calling is the thread's start method.
Also as Mick stated, setting stopRunning as volatile should help. The reason it should work is that it will remove the caching of the variable in the thread's memory and will get/set directly from memory.

Related

Why the program without 'volatile' works as 'volatile'?

As typed below, the program has a shared var flag without volatile:
public class T {
public static void main(String[] args) {
TT jump = new TT(() -> {
while (true) {
if (TT.flag) {
System.out.println("jump");
break;
}
}
});
jump.start();
new TT(() -> {
TT.flag = true; // P1
LocalDateTime t1 = LocalDateTime.now();
while (true) {
if (Duration.between(t1, LocalDateTime.now()).toMillis() > 100) {
break;
}
}
System.out.println("flag");
}).start();
}
static class TT extends Thread {
public static boolean flag = false;
public TT(Runnable o) {
super(o);
}
}
}
The program always returns normally. So I believe the line of P1 ,where the flag was set to true, updated flag in other threads.
But why? flag is not volatile, why its value was updated immediately? Always!
But why? flag is not volatile, why its value was updated immediately? Always!
You are simply lucky; or unlucky, depending upon your perspective. I tried this on Ideone, and found that it timed out rather than terminating normally.
Remember: not being able to observe a concurrency bug is not the same as an absence of a concurrency bug.
The most sure you can be about code is when you can prove, according to the specification, that there are no bugs. That doesn't mean that the code will then work correctly; it just means that the problems are in the JVM implementation.
In particulary, you can't prove that this code will work correctly, because there is no happens-before relationship between the write to flag in the second thread, and the read in the first thread. Adding volatile creates this guarantee, because a volatile write happens before a volatile read.
That's not to say it will never work without volatile, it's just not guaranteed: a JVM only has to flush a thread's cached values at least as often as the spec requires, but can do it more often, or indeed not cache values at all.

Java8: How volatile field work with lambda

I am new to Java8 and multithreading work. I tried this piece of code below
public class Test {
public static boolean bchanged = true;
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
while (true) {
if (bchanged != bchanged) {
System.out.println("here");
}
}
}
}
).start();
new Thread((Runnable) () -> {
while (true) {
bchanged = !bchanged;
}
}).start();
}
}
when I was running this code, there is no print of "here". However, when I change
public static volatile boolean bchanged = true;
then the "here" will be printed out.
My original deduction was that, the lambda will have a local copy of the boolean value, and it won't affect the other thread when it is not volatile, but when I tried print out the boolean value in both threads, it proved I was wrong. So I am very confused in this case, how volatile affect the way lambda work.
This isn't about lambdas, this is about accessing a shared variable in multiple threads. You need to use synchronized, locks, AtomicBoolean, volatile, or some other thread-safety alternative. With the code you wrote the compiler is likely to cache the value of bchanged. It doesn't know that there's another thread modifying it, so the first thread sees a stale cached value.
As described in other answers, volatile and lambda has nothing to do together.
Volatile is printing "here" because the value of variable "bchanged" is not cached as "the volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache value of this variable and always read it from main memory".
You can use below links to understand more on volatile.
Read more: http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html#ixzz4ZlvIJYzZ
Cave of Programming: https://www.youtube.com/watch?v=_aNO6x8HXZ0&t=113s

How synchronization helps in variable visibility?

public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
According to "Java Concurrency in Practice", it may be possible that it will print 0 as write to ready might be made visible to the reader thread before write to a number or program never terminate at all because it does not use adequate synchronization. It is not guaranteed that values of ready and number written by main thread will be visible to reader thread.
How is it possible? Program will be run sequentially by a thread and it first writes to number and then ready variable. Isn't it? And how can this program could loop forever?
There are no guarantees that by changing a variable in one thread, other threads will see the results of those changes. Technically there is no happens-before relation between them and thus no guarantees (whilst in practice you'll see the changes almost all the time).
That's why the thread may run forever.
Secondly, why sometimes 0 ?
Well the JLS says that
Writes in one thread that are in a data race with reads in another
thread may, for example, appear to occur out of order to those reads.
Which means that your
number = 42;
ready = true;
Can occur in any order. Now it's more likely they'll appear in order, but again there's no guarantees.
You could fix it by changing the variables to be volatile, in which case the writes will always be visible to the readers or by making the code where you mutate state a critical section (see the book). In general I feel using too many volatile variables is a bit of a hack, so you should try and use them sparingly, for things like thread "running" variables.
public class NoVisibility {
private static volatile boolean ready;
private static volatile int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
If ready is not marked as 'volatile' than the ReaderThread might check its value (as 0).
It later does not check again about ready's value because it assume it has not changed.
The volatile keyword instructs the compiler not to have such assumptions at all and that the variable's value might change under his feet.

How to interrupt an Infinite Loop

Though I know it'll be a bit silly to ask, still I want to inquire more about the technical perspective of it.
A simple example of an infinite loop:
public class LoopInfinite {
public static void main(String[] args) {
for (;;) {
System.out.println("Stack Overflow");
}
}
}
How can I interrupt (stop) this infinite loop from outside of this class (e.g., with the help of inheritance)?
I feel dirty even writing this, but...
From a different thread, you could call System.setOut() with a PrintStream implementation, which throws a RuntimeException when you call println().
We can achieve it using volatile variable, which we will change ouside Thread and stop the loop.
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
This is better way to write Infinite Loop.
public class LoopInfinite{
private static volatile boolean cancelled=false;
public static void main(String[] args){
for(;!cancelled;) { //or while(!cancelled)
System.out.println("Stackoverflow");
}
}
public void cancel(){
cancelled=true;
}
}
You can get at the thread running the infinite loop from a different thread and call interrupt on it. You'll have to be very sure what you are doing though, and hope that the interrupted thread will behave properly when interrupted.
Here, I've named the thread with the offending loop for easier identification. Beware that the following solution is vulnerable to race conditions.
Thread loop = new Thread() {
public void run() {
Thread.currentThread().setName("loop");
while(true) {
System.out.print(".");
}
}
}.start();
Then in some other class:
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
for(Thread t : threads) {
if(t.getName().equals("loop")) {
/* Thread.stop() is a horrible thing to use.
Use Thread.interrupt() instead if you have
any control over the running thread */
t.stop();
}
}
Note that in my example I assume the two threads are in the same ThreadGroup. There is no guarantee that this will be the case, so you might need to traverse more groups.
If you have some control over this, a decent pattern here would be to have while(!isInterrupted()) instead in the loop declaration and use t.interrupt() instead of t.stop().
My only advice to you, even after posting this, is to not do this. You can do it, but you really shouldn't.
I think this is not possible. Only using break within the loop. You could use
while(cond) {}
And from some other place make it false
You can interrupt this thread by keeping its static reference of inherited reference to this Thread [main] by asking from Thread.currentThread(), like this
public class LoopInfinite{
public static Thread main = null;
public static void main(String[] args){
main = Thread.currentThread();
for(;;)
System.out.println("Stackoverflow");
}
}
And to terminate you can call this from some other thread
LoopInfinite.main.interrupt();
But it will only work if both threads are part of the same group. Otherwise calling thread will get SecurityException
You cannot stop this from outside of this class. If you use inheritance you can overwrite your loop, but without abort-flag you won't be able to do so.
Very open question, but stopping such loop would most likely require you to operate from another thread. The other thread would then need to set some variable that your infinite loop can check regularly, and if the variable has a certain value; break out of the loop.
You won't be able to interrupt this particular loop without halting the process entirely. In general, if you're trying to do it from an external source (I'm assuming you have no control over the source code, because if you did you could easily set a condition in the loop, such as a boolean you could set from an external Thread), you will have to halt the running Thread, whether you do this through the Thread object (you'll have to find a reference to it somehow, for example by looping through existing Threads), or whether you halt it as a system process.
Another option would be to override the method with a loop that isn't an infinite loop, but unfortunately that doesn't apply to your example because it's a static method.
Your kind of problem looks like a Threading problem. But still, it is now a a good practice to include a stopping flag even in threads
If you need an "infinite" loop, you sure need a thread (else your app will be stuck until the end of the loop).
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
So, this is a simple method to have background running loop.
Add a variable shouldBreak or something which can be set using getter and setter.
public class LoopInfinite {
private boolean shouldBreak = false;
public boolean isShouldBreak() {
return shouldBreak;
}
public void setShouldBreak(boolean shouldBreak) {
this.shouldBreak = shouldBreak;
}
public static void main(String[] args) {
// Below code is just to simulate how it can be done from out side of
// the class
LoopInfinite infinite = new LoopInfinite();
infinite.setShouldBreak(true);
for (;;) {
System.out.println("Stackoverflow");
if (infinite.shouldBreak)
break;
}
}
}
Here is what I did:
while(Exit == false){
Scanner input = new Scanner(System.in);
String in = input.next();
switch(in){
case "FindH":
FindHyp hyp = new FindHyp();
float output = hyp.findhyp();
System.out.println(output);
case "Exit":
Exit = true;
break;
}
}

Using ThreadLocal in tandem with Volatile gives unpredictable results

I was reading through Java Memory model and was playing with volatile. I wanted to check how Volatile will work in tandem with ThreadLocal. As per definition ThreadLocal has its own, independently initialized copy of the variable whereas when you use volatile keyword then JVM guarantees that all writes and subsequent reads are done directly from the memory. Based on the high level definitions i knew what i was trying to do will give unpredictable results. But just out of curiosity wanted to ask if someone can explain in more details as if what is going on in the background. Here is my code for your reference...
public class MyMainClass {
public static void main(String[] args) throws InterruptedException {
ThreadLocal<MyClass> local = new ThreadLocal<>();
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(local.get());
thread.start();
}
}
}
public class MyClass implements Runnable {
private volatile boolean flag = false;
public void printNameTillFlagIsSet(){
if(!flag)
System.out.println("Flag is on for : " + Thread.currentThread().getName());
else
System.out.println("Flag is off for : " + Thread.currentThread().getName());
}
#Override
public void run() {
printNameTillFlagIsSet();
this.flag = true;
}
}
In your code you create a ThreadLocal reference as a local variable of your main method. You then store an instance of MyClass in it and then give that same reference of MyClass to 5 threads created in the main method.
The resulting output of the program is unpredictable since the threads are not synchronized against each other. At least one thread will see the flag as false the other four could see the flag as either true or false depending on how the thread execution is scheduled by the OS. It is possible that all 5 threads could see the flag as false, or 1 could see it false and 4 see it true or anything in between.
The use of a ThreadLocal has no impact on this run at all based on the way you are using it.
As most have pointed out you have deeply misunderstood ThreadLocal. This is how I would write it to be more accurate.
public class MyMainClass {
private static final ThreadLocal<MyClass> local = new ThreadLocal<>(){
public MyClass initialValue(){
return new MyClass();
}
}
public static void main(String[] args) throws InterruptedException {
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(new Runnable(){
public void run(){
local.get().printNameTillFlagIsSet();
local.get().run();
local.get().printNameTillFlagIsSet();
}
});
thread.start();
}
}
}
So here five different instances of MyClass are created. Each thread will have their own accessible copy of each MyClass. That is Thread created at i = 0 will always have a different instance of MyClass then i = 1,2,3,4 despite how many local.get() are done.
The inner workings are a bit complicated but it can be done similar to
ConcurrentMap<Long,Thread> threadLocalMap =...;
public MyClass get(){
long id = Thread.currentThread().getId();
MyClass value = threadLocalMap.get(id);
if(value == null){
value = initialValue();
threadLocalMap.put(id,value);
}
return value;
}
To further answer your question about the volatile field. It is in essence useless here. Since the field itself is 'thread-local' there will be no ordering/memory issues that can occur.
Just don't divinize the JVM. ThreadLocal is a regular class. Inside it uses a map from current thread ID into an object instance. So that the same ThreadLocal variable could have its own value for each thread. That's all. Your variable exists only in the main thread, so it doesn't make any sence.
The volatile is something about java code optimization, It just stops all possible optimizations which allow avoid redundant memory reads/writes and execution sequence re-orderings. It is important for expecting some particular behaviour in multi-threaded environment.
You have two big problems:
1) As many pointed out, you are not using ThreadLocal properly so you don't actually have any "thread local" variables.
2) Your code is equivalent to:
MyClass someInstance = new Class();
for (...)
... new Thread(someInstance);
so you should expect to see 1 on and 4 off. However your code is badly synchronized, so you get random results. The problem is that although you declare flag as volatile, this is not enough for good synchronization since you do the check on flag in printNameTillFlagSet and then change the flag value just after that method call in run. There is a gap here where many threads can see the flag as true. You should check the flag value and change it within a synchronized block.
You main thread where you have a ThreadLocal object is being passed to all the threads. So the same instance is being passed.
So its as good as
new Thread(new MyClass());
What you could try is have an object being called by different threads with a thread local variable. This will be a proper test for ThreadLocal where each thread will get its own instance of the variable.

Categories

Resources