Strange behavior in Java with unsyncronized access in a multithreading program - java

I change a value that is used to determine when a while-loop terminates in a seperate thread.
I don't want to know how to get this working. If I access the variable test only through synchronized getters/setters it works as expected..
I would have expected, if some read/write commands are lost due to concurrency the program sometimes does not terminate, but it never does. Thats what confuses me..
I would like to know why the program never terminates, without the print-command. And I would like to understand why the print-command changes anything..
public class CustomComboBoxDemo {
public static boolean test = true;
public static void main(String[] args) {
Thread user =new Thread(){
#Override
public void run(){
try {
sleep(2000);
} catch (InterruptedException e) {}
test=false;
}
};
user.start();
while(test) {
System.out.println("foo"); //Without this line the program does not terminate..
}
}
}

The most likely explanation is that the variable is only read once, turning the while into an infinite loop (or a no-op). Since you haven't declared test as volatile, the compiler is allowed to perform such an optimization.
Once you call an external function from within the loop, the compiler can no longer prove that test remains invariant across loop iterations, and doesn't perform the optimization.

If the test variable is not defined as volatile, the compiler probably optimizes the loop containing no operation into a while(true) loop for your main thread and the program never ends.
Otherwise, the value of the test variable is actually checked and when your second thread changes its value, then the main thread leaves the while loop and your program terminates.

I presume it's something to do with the way IO is handled. Without the print, you'll probably see the java application using all available CPU time; with the print it's likely that IO delays give up enough CPU time for other processing to take place.
A quick way to test this theory would be to put printlns in the run() method of your thread to see whether the thread is actually ever executing. In my experience, infinite empty loops cause a lot of strange behaviour.
That said, it appears to terminate fine on my workstation under JDK 1.6.0_10_b23

Seems like your loop is being incorrectly compiled away into a busy-wait. Adding a volatile keyword to your boolean corrects the 'problem'.

public static boolean test = true;
public static void main(String[] args) {
Thread user =new Thread(){
#Override
public void run(){
try {
sleep(2000);
} catch (InterruptedException e) {}
test=false;
System.out.println("Thread.end <"+test+">");
}
};
user.start();
while(test);
}
That's interesting. The compiler most probably optimzes this while into an endless loop, not reading the value at each loop.
Defining test as volatile fixes this and let your program terminate
Btw: you probably already know that you shoud use user.join() to wait for the Thread to end

I don't understand what you are trying to do by using code you know is not correctly synchronized.
As some have reported, on their machine the code behaves differently than on your machine. The behavior of badly synchronized code is undefined. It makes no sense to try to understand what it does since that behavior will change with the JVM version or architecture.

Related

Killing a thread or an asynchronous task

let's say I use a jar that IBM has created.
Let's say that this Jar has a function that I need but is ultimately build as such:
while (true) {
System.out.println(1)
}
(of course it doesn't really just printing 1, but for the example let's say it is)
So, I made the call to the function that does it in another thread using future. How can I completely kill the thread that this code is running in? Or alternatively, how can I kill the asynchronous task in Kotlin that runs the code.
Solutions in Kotlin or Java will be great,
thanks in advance!
EDIT:
I've found out, that if this is a thread, I can Thread#stop() it to really make it stop. But unfortunately making the constructor throwing exceptions multiple times, causes the JVM to erase the class from memory causing a NoClassDefFoundError when instantiating the class the next time..
If you can capture it's thread you should be able to kill it so long as it is doing some kind of blocking function internally.
class OtherFunction implements Runnable {
#Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We assume the thread will exit when interrupted.
System.out.println("Bye!!");
return;
}
System.out.println("Hello");
}
}
}
class Killable implements Runnable {
final Runnable target;
private Thread itsThread;
Killable(Runnable target) {
this.target = target;
}
#Override
public void run() {
// Catch the thread id of the target.
itsThread = Thread.currentThread();
// Launch it.
target.run();
}
public void kill() {
// Give it a good kick.
itsThread.interrupt();
}
}
public void test() throws InterruptedException {
OtherFunction theFunction = new OtherFunction();
Killable killableVersion = new Killable(theFunction);
new Thread(killableVersion).start();
// Wait for a few seconds.
Thread.sleep(10000);
// Kill it.
killableVersion.kill();
}
It seems like Thread#stop() solved my problem. I know it's deprecated and can be prevented with catch(Throwable t) but at least it did the trick for me.
By the way, to get the thread from the executor, I've used AtomicReference<Thread> and set it in the callback.
Thread#stop() is deprecated as 'inherently unsafe' and should be avoided if at all possible.
It's a source of instability and corruption and may fail anyway!
It actually causes a ThreadDeath exception to be throw in the target thread.
The authors of whatever code it pops into are unlikely to have expected that outcome.
Objects may be in an inconsistent state, external resources may be held and get leaked, files may be incompletely written.
There are ways of handling unexpected errors but in practice most code is written assuming it knows which exceptions might be thrown and not in anticipation for such a 'surprise'.
Given ThreadDeath is a Throwable any catch(Throwable t) will catch it and again, unless great care was taken in every piece of code the thread might execute (unrealistic) ThreadDeath might just get absorbed and not end the thread.
The correct way to handle this is declare an atomic variable (usually as part of the Runnable that represents the task.
AtomicBoolean stopThread=new AtomicBoolean(false);
Then write the loop as:
while (!stopThread.get()) {
System.out.println(1);
}
And provide a method:
public void stopThread(){
stopThread.set(true);
}
Alternatively you can use interrupt() and check interrupted(). These are cleaner methods provided in the Thread class. interrupted() has the behaviour of clearing the flag when called. That's not always helpful and while the flag can be examined by Thread.currentThread().isInterrupted() the 'checking the flag clears it' behaviour can be unhelpful and also suffers some of the issues of stop() because it can cause "surprising" exceptions to be throw at points other code has never anticipated. The right approach is to use your own flag and be in full control of where the process decides to quit.
Take your pick.
See also: Java Thread Primitive Deprecation
Ever wondered why when you click 'Cancel' on some concurrent process you are often made to wait ages for it to respond?
This is why. The task needs to come to a well defined point and do any necessary clean up to terminate in a well defined way.
Think of Thread#stop() as like stopping a cyclist by kicking them off their bike. The method here waves a red flag at them and they then come to a halt as swiftly as they safely can.
Thread#stop() should never have been in Java and you should never use it.
You get away with it in development and small systems. It causes havoc in large production environments.
It's not just deprecated as 'not recommended' it is 'inherently unsafe' do not use it.
It's been deprecated for years and its disappointing that some 'removal date' has never been advertised.
Here's an example that uses either Thread#stop() or interrupt() depending on whether you opt for being dangerous.
import java.lang.System;
import java.lang.Thread;
class Ideone
{
private static boolean beDangerous=true;//Indicates if we're going to use the Thread#stop()....
//This main method uses either stop() or interrupt() depending on the option.
public static void main (String[] args) throws java.lang.Exception
{
PrimeFactor factor=new PrimeFactor();
try{
for(int i=1;i<30;++i){
Thread thrd=new Thread(new Primer(factor));
thrd.start();
Thread.sleep(10);//Represents some concurrent processing...
if(beDangerous){
thrd.stop();
}else{
thrd.interrupt();
}
thrd.join();
if(!factor.check()){
System.out.println("Oops at "+i);
}
}
}catch(Throwable t){
System.out.println(t);
}
}
//This class just hammers the PrimeFactor object until interrupt()ed (or stop()ed).
private static class Primer implements Runnable {
private PrimeFactor factor;
public Primer(PrimeFactor ifactor){
factor=ifactor;
}
public void run(){
int i=1;
while(!Thread.interrupted()){
factor.set(i++);
}
}
}
//Don't worry about this bit too much.
//It's a class that does a non-trivial calculation and that's all we need to know.
//"You're not expected to understand this". If you don't get the joke, Google it.
//This class calculates the largest prime factor of some given number.
//Here it represents a class that ensures internal consistency using synchronized.
//But if we use Thread#stop() this apprently thread-safe class will be broken.
private static class PrimeFactor {
private long num;
private long prime;
public static long getFactor(long num){
if(num<=1){
return num;
}
long temp=num;
long factor=2;
for(int i=2;temp!=1;++i){
if(temp%i==0){
factor=i;
do{
temp=temp/i;
}while(temp%i==0);
}
}
return factor;
}
public synchronized void set(long value){
num=value;
prime=getFactor(value);
}
public synchronized boolean check(){
return prime==getFactor(num);
}
}
}
Typical partial output:
Oops at 1
Oops at 2
Oops at 3
Oops at 6
Oops at 8
Notice that the PrimeFactor class can be described as thread-safe. All it's methods are synchronized. Imagine it's in some library. It's unrealistic to expect "thread-safe" to mean Thread#stop()-safe and the only way to do that would be intrusive. Putting calls to it in a try-catch(ThreadDeath tde) block won't fix anything. The damage will have been down before it's caught.
Don't convince yourself that changing set() to the following solves it:
public synchronized void set(long value){
long temp=getFactor(value);
num=value;
prime=temp;
}
First and foremost the the ThreadDeath exception could throw during the assignments so all that does is potentially shorten the odds on the Race Condition. It hasn't been negated. Never make "how likely is that to happen" arguments about race conditions. Programs call methods billions of times so billion to one-shots come up regularly.
To use Thread#stop() you can essentially never use any library objects including java.* and jump through hoops to handle ThreadDeath everywhere in your code and almost certainly eventually fail anyway.
In java there is no official way of killing thread. This is bug. (no need to argue with it here) Thread#stop() should not be deprecated. It may be improved that it cannot be consumed. Even now it will work most of the time just fine.
Right now, if I write function which will be executed with kill need, I would start new thread and joint to it with timeout or other disconnect mechanism. This will make your code to continue like main thread was killed. Problem is that main thread is still running. All resources are still in use. This is still better than application being frozen. Calling thread.interrupt() is first step but it this does not work using thread.stop() is adequate here. It won't make things worse.
If you really must kill the thread, only way would be to start another jvm via jni, run unsafe code there and use linux kill -9 to stop the whole process if needed.
I believe killing thread is perfectly possible, only jvm developers didn't care enough. I get into this situation all the time and answers like don't use any libraries, fix all foreign code, write your own language or live with it are just frustrating.

Why is this code working without volatile?

I am new to Java, I am currently learning about volatile. Say I have the following code:
public class Test
{
private static boolean b = false;
public static void main(String[] args) throws Exception
{
new Thread(new Runnable()
{
public void run()
{
while(true)
{
b = true;
}
}
}).start();
// Give time for thread to start
Thread.sleep(2000);
System.out.println(b);
}
}
Output:
true
This code has two threads (the main thread and another thread). Why is the other thread able to modify the value of b, shouldn't b be volatile in order for this to happen?
The volatile keyword guarantees that changes are visible amongst multiple threads, but you're interpreting that to mean that opposite is also true; that the absence of the volatile keyword guarantees isolation between threads, and there's no such guarantee.
Also, while your code example is multi-threaded, it isn't necessarily concurrent. It could be that the values were cached per-thread, but there was enough time for the JVM to propagate the change before you printed the result.
You are right that with volatile, you can ensure/guarantee that your 2 threads will see the appropriate value from main memory at all times, and never a thread-specific cached version of it.
Without volatile, you lose that guarantee. And each thread is working with its own cached version of the value.
However, there is nothing preventing the 2 threads from resynchronizing their memory if and when they feel like it, and eventually viewing the same value (maybe). It's just that you can't guarantee that it will happen, and you most certainly cannot guarantee when it will happen. But it can happen at some indeterminate point in time.
The point is that your code may work sometimes, and sometimes not. But even if every time you run it on your personal computer, is seems like it's reading the variable properly, it's very likely that this same code will break on a different machine. So you are taking big risks.

Multi-threading -- a faster way?

I have a class with a getter getInt() and a setter setInt() on a certain field, say field
Integer Int;
of an object of a class, say SomeClass.
The setInt() here is synchronized-- getInt() isn't.
I am updating the value of Int from within multiple threads.
Each thread is getting the value Int, and setting it appropriately.
The threads aren't sharing any other resources in any way.
The code executed in each thread is as follows.
public void update(SomeClass c) {
while (<condition-1>) // the conditions here and the calculation of
// k below dont have anything to do
// with the members of c
if (<condition-2>) {
// calculate k here
synchronized (c) {
c.setInt(c.getInt()+k);
// System.out.println("in "+this.toString());
}
}
}
The run() method is just invoking the above method on the members updated from within the constructor by the params passed to it:
public void run() { update(c); }
When I run this on large sequences, the threads aren't interleaving much-- i see one thread executing for long without any other thread running in between.
There must be a better way of doing this.
I can't change the internals of SomeClass, or of the class invoking the threads.
How can this be done better?
TIA.
//=====================================
EDIT:
I'm not after manipulating the execution sequence of the threads. They all have the same priority. It`s just that what i see in the outcome is suggesting that the threads aren't sharing the execution time evenly-- one of them, once takes over, executing on. However, I can't see why this code should be doing this.
It`s just that what i see in the outcome is suggesting that the threads aren't sharing the execution time evenly
Well, this is exactly what you don't want if you are after efficiency. Yanking a thread from being executed and scheduling another thread is generally very costly. Therefore it's actually advantageous to do one of them, once takes over, executing on. Of course, when this is overdone you could see higher throughput but longer response time. In theory. In practice, JVMs thread scheduling is well tuned for almost all purposes, and you don't want to try changing it in almost all situations. As a rule of thumb, if you are interested in response times in millisecond order, you probably want to stay away messing with it.
tl;dr: It's not being inefficient, you probably want to leave it as it is.
EDIT:
Having said that, using an AtomicInteger may help in performance, and is in my opinion less error prone than using a lock (synchronized keyword). You need to be hitting that variable really very hard in order to get a measurable benefit though.
The JDK provides a nice solution for multi threaded int access, AtomicInteger:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html
As Enno Shioji has pointed out, letting one thread proceed might be the most efficient way to execute your code in some scenarios.
It depends on how much cost the thread synchronization imposes in relation to the other work of your code (which we don’t know). If you have a loop like:
while (<condition-1>)
if (<condition-2>) {
// calculate k here
synchronized (c) {
c.setInt(c.getInt()+k);
}
}
and the test for condition-1 and condition-2 and the calculation of k is rather cheap compared to the synchronization cost, the Hotspot optimizer might decide to reduce the overhead by transforming the code to something like this:
synchronized (c) {
while (<condition-1>)
if (<condition-2>) {
// calculate k here
c.setInt(c.getInt()+k);
}
}
(or a rather more complicated structure by performing loop unrolling and span the synchronized block over multiple iterations). The bottom line is that the optimized code might block other threads longer but let the one owning the lock finish faster resulting in an overall faster execution.
This does not mean that a single-threaded execution was the fastest way to handle your problem. It also doesn’t mean that using an AtomicInteger here would be the best option to solve the problem. It would create a higher CPU load and possibly a small acceleration but it doesn’t solve your real mistake:
It is completely unnecessary to update c within the loop at a high frequency. After all, your threads do not depend on seeing updates to c timely. It even looks like they are not using it at all. So the correct fix would be to move the update out of the loop:
int kTotal=0;
while (<condition-1>)
if (<condition-2>) {
// calculate k here
kTotal += k;
}
synchronized (c) {
c.setInt(c.getInt()+kTotal);
}
Now, all threads can run in parallel (assuming the code you haven’t posted here doesn’t contain inter-thread dependencies) and the synchronization cost is reduced to a minimum. You could still change it to an AtomicInteger as well but that’s not that important anymore.
Answering to this
i see one thread executing for long without any other thread running in between.
There must be a better way of doing this.
You can not control how threads will be executed. JVM does this for you, and does not like you to interfere in its work.
Still you can look at yield as your option, but that also does not ensure same thread will not be picked again.
The java.lang.Thread.yield() method causes the currently executing thread object to temporarily pause and allow other threads to execute.
I've found it better to use wait() and notify() than yield. Check out this example (seen from a book)-
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
wait(); //handle InterruptedException
//
valueSet = false;
notify();//if thread waiting in put, now notified
}
synchronized void put(int n) {
if(valueSet)
wait(); //handle InterruptedException
//
valueSet = true;
//if thread in get waiting then that is resumed now
notify();
}
}
or you could try using sleep() and join the threads in the end in main() but that isn't a foolproof way
You are having public void update(SomeClass c) method in your code and this method is an instance method in which you are passing the object as parameter.
synchronized(c) in your code is doing nothing. Let me show you with some example,
So if you will make different objects of this class and then try to make them different threads like,
class A extends Thread{
public void update(SomeClass c){}
public void run(){
update(c)
}
public static void main(String args[]){
A t1 = new A();
A t2 = new A();
t1.start();
t2.start();
}
}
Then both of these t1 & t2 will have their own copies of update method and the reference variable c which you are making synchronized will also be different for both the threads. t1 calls its own update() method and t2 calls its own update() method. So synchronization won't work.
Synchronization will work when you have something common for both the threads.
Something like,
class A extends Thread{
static SomeClass c;
public void update(){
synchronized(c){
}
}
public void run(){
update(c)
}
public static void main(String args[]){
A t1 = new A();
A t2 = new A();
t1.start();
t2.start();
}
}
This way the actual concept of synchronization will be applied.

Processing statement error in loop

public static void main(String[] args) throws IOException {
// new fetchEmailID().fetchIDs();
new UserInputAndDefaulValues().validateUserInputAndDefaultValues();
while(!UserInputAndDefaulValues.start_mailing_flag)
{
//System.out.println(UserInputAndDefaulValues.start_mailing_flag);
}
MainExecutor.main_executor();
}
When I uncomment
//System.out.println(UserInputAndDefaulValues.start_mailing_flag);
the condition in while loop works correctly and the while loop ends on false condition. But as I comment it, the loop goes in infinite loop even when it should escape. Why is that behavior and that too just with one output statement?
First and foremost, your code is not correctly synchronized. In other words, it contains a data race on the start_mailing_flag.
Now, the method PrintStream#println is synchronized so calling it forces the JIT compiler to avoid certain optimizations (namely, hoisting) on the code in question. As soon as you remove that statement, the effect is gone.
To conclude, when you uncomment the println, your code works by pure chance and as a side-effect of calling a synchronized method. It remains as thread-unsafe as before.
I'm guessing you change the start_mailing_flag in another thread (otherwise, no wonder the loop goes on forever).
The compiler optimizes such cases and removes the condition check after the first time. It changes the code to something like this:
if (!UserInputAndDefaulValues.start_mailing_flag) {
while(true)
{
//System.out.println(UserInputAndDefaulValues.start_mailing_flag);
}
}
You need to define start_mailing_flag as volatile:
public class UserInputAndDefaulValues {
public static volatile boolean start_mailing_flag;
.....
}

Infinite loop problem with while loop and threading [duplicate]

This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 8 years ago.
Using a basic example to illustrate my problem I have 2 near-identical bits of code.
This code causes the while loop to run infinitely.
private boolean loadAsset() {
new Thread(new Runnable() {
#Override
public void run() {
// Do something
loaded = true;
}
}).start();
while (!loaded) {
// System.out.println("Not Loaded");
}
System.out.println("Loaded");
return false;
}
This code however (i.e. doing something in the while loop) causes the loaded variable to be successfully evaluated and allows the while loop to break and method to finish.
private boolean loadAsset() {
new Thread(new Runnable() {
#Override
public void run() {
// Do something
loaded = true;
}
}).start();
while (!loaded) {
System.out.println("Not Loaded");
}
System.out.println("Loaded");
return false;
}
Can anyone explain to me why this is?
The first loop only "appears" to run infinitely. You're actually running an "active wait", burning 100% of your CPU, such that your OS or JVM can't make a context switch and let the other thread run.
With the System.out.println() on the other hand, there is I/O involved, resulting in a somewhat "inactive wait". The OS or JVM can switch contexts and the other thread starts.
If you'd run your first program for 10 hours, I'm sure the loop would break eventually
Check that 'loaded' is definitely declared as volatile.
Explanation: if a variable is read and/or written by multiple threads, then you need to take appropriate thread-safety measures. One such thread-safety measure is volatile, which is suitable for primitive values (or object references) which are read or written as 'simple' actions with the value written on a given occasion not depending on the previously read value. For more information, I have an article about volatile on my web site (along with other information about thread-safety generally) that may be of help.
If loaded is not volatile, the JIT is free to optimise it by placing it in a register and not loading it from memory every time. In the second case, the loop is too complex for the JIT to assume it doesn't need to load loaded each time.
Note: its is the JIT not the javac compiler which optimises the code.
Read up on Memory Consistency Errors. Basically, different threads have inconsistent views of what should be the same data. In order to resolve this, read up on Synchronization. Or simply declare loaded as volatile, since its value is only being written by a single thread.
I believe you are experiencing a Busy Wait with the empty loop, which will never sleep. Thus, your Thread to set loaded to true never runs.

Categories

Resources