Processing statement error in loop - java

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

Related

Using break and return in Java's synchronizedList performs unwanted behavior

I'm new at using synchronizedLists in Java, and I'm running into a problem - I'm trying to do something like this
public void foo(List<String> list) {
List<String> syncList = Collections.synchronizedList(list);
synchronized(syncList) {
Iterator<String> itr = syncList.iterator();
while(itr.hasNext()) {
String s = itr.next();
if(s == null) {
return;
}
doStuff();
}
}
}
But I've noticed that when I run this doStuff() doesn't seem to be run on each of the non-null items in the list. I've tried experimenting with swapping out return for break and continue, and I've found that doStuff() is also not run on the non-null list items with break. With continue, the non-null list items do get doStuff() run on them but since continue just skips to the next iteration of the loop it makes this operation much more expensive than desired.
Why is this happening and what is the best workaround?
edit: Forgot to add that when I run this sequentially with return, it works fine.
break exits the loop. It makes execution jump to the first line of code outside the loop.
return exits the function, and naturally the loop contained in the function. The execution continues where this function was called.
With continue, the non-null list items do get doStuff() run on them but since continue just skips to the next iteration of the loop it makes this operation much more expensive than desired.
I don't understand - what operation is more expensive in what way than you desire?
Either way, nothing here has to do with synchronization or parallel programming. The way Collections.synchronizedList and synchronized(syncList) are being used is pointless: there's no way another thread can access them.

Why variable visible to other thread without synchronization? [duplicate]

This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 5 years ago.
I have theoretical question about memory visibility. Here is sample code:
public class TwoThreadApp {
private static class A {
int x = 1;
}
public static void main(String[] arg) throws InterruptedException {
A a = new A();
Thread t2 = new Thread(() -> {
while (true) {
if (a.x == 2) {
System.out.println(a.x);
return;
}
// IO operation which makes a.x visible to thread "t2"
System.out.println("in loop");
}
});
t2.start();
Thread.sleep(100);
a.x = 2;
}
}
Without System.out.println("in loop") programs works indefinitely, which is expected behavior.
But with System.out.println("in loop") it is always completes, which is not expected, because a.x is not volatile and there is no synchronized blocks.
My env: ubuntu 16.04, openjdk 1.8.0_131
Why it behaves this way?
Without System.out.println("in loop") programs works indefinitely, which is expected behavior.
On the contrary, the program should quit. The program keeps going, that is side-effect of fact that x is cached (as non volatile). The caching is compiler's optimalization and you should not rely on it (depending on JVM settings).
But with System.out.println("in loop") it is always completes, which is not expected, because a.x is not volatile and there is no synchronized blocks.
This is IMHO expected behaviour. I cannot tell you why, I'd assume the IO operations are involved to clear the thread cache (please comment/correct if someone is having better insight).
Accessing variables without synchronization or locks or being volatile with multiple threads may be really unpredictable.
You can even disable many optimalizations with -Djava.compiler=NONE (then the program should always quit as expected)
IMHO this is something to do with Compiler optimization I think. In your first example compile can decide to move the If condition outside while loop like
if(a.x == 2) while(true) {...}
In 2nd case as you are using println which internally uses synchronized keyword compiler may not optimize the code as above.
This is what I think and I maybe wrong.
Edit: You can also refer here : Loop doesn't see changed value without a print statement

executing block of code atomically

How would you answer the following question?
A method of a java class contains a block of code that must be
executed atomically. Explain, using appropriate pseudo-code, how you
would ensure that this block of code is executed atomically
Would I achieve this by making the method ..
public final AtomicInteger x = new AtomicInteger(0);
then ensuring the get statement returned:
x.get()
and if I wanted to increment the value of x would I do this?
x.getAndIncrement();
The answer depends on your definition of "atomic"
I know of three valid definitions for atomic:
Atomic as in synchronized: only one thread can be executing the code at one time;
Atomic as in ACID: all of the action/block happens, or none of it does;
Atomic as in uninterruptible: once the block starts, it can't be interrupted, even by task switching.
The first is probably what your professor meant, and it's pretty easy to accomplish (see below).
The second (atomic as in ACID) can be approximated. See below.
The third simply cannot be guaranteed in Java - it doesn't provide access to the "critical sections" primitives required for uninterruptibility. Fortunately, the need for this is pretty much restricted to operating systems and device drivers.
Atomic as in synchronized
This is relatively straightforward: simply enclose your block of code in a synchronized block. I've shown it as a discrete block below, but there are other options:
public void doSomethingQuasiAtomic() {
synchronized (exampleLock) {
// Your code block goes here.
// Only one thread will ever be in this block at a time.
...
}
}
Atomic as in ACID
There's no general-case solution for ACID atomicity, but it can be approximated, also using synchronized code. In order to do this, each of the parts of the action must be safely reversible.
This is how I'd approach it:
For the sake of argument, assume there's a multipart action you need to do on an object we'll call exampleObj, that you have three actions to be performed which can be safely reversed, and that all access to example is synchronized on exampleLock.
synchronized(exampleLock) {
boolean actionOneDone=false;
boolean actionTwoDone=false;
boolean actionThreeDone=false;
try {
actionOneDone=doActionOne(exampleObj); // or perhaps exampleObj.doActionOne();
if(actionOneDone) actionTwoDone=doActionTwo(exampleObj);
if(actionTwoDone) actionThreeDone=doActionThree(exampleObj);
} catch (Exception ex) {
// Whatever seems appropriate here.
} finally {
if (! (actionOneDone && actionTwoDone && actionThreeDone)) {
/* At least one part failed. Back out the completed actions in reverse order.
* Note that we never need to reverse action three since if it completed, so did the others.
*/
if (actionTwoDone) {
reverseActionTwo(exampleObj); // or perhaps exampleObj.reverseActionTwo();
}
if (actionOneDone) {
reverseActionOne(exampleObj);
}
}
}
}
I believe that the expected answer was something like this:
public class A {
public void foo() {
// .. some code
doSomething(); // the critical part
// .. come code
}
public synchronized void doSomething() { // this is a synchronized method
// the critical code
}
}
The execution of doSomething() is not really atomic (Disclaimer: it's very different from atomicity), but the synchronized keyword ensures that only one thread can enter the execution of this method (on one instance of A). I think that is what they meant instead of atomicity.
Here is another question about atomicity in Java. You may find something useful in there.

how can more than one thread execute my method?

hey i'm sorry to be asking this here, but my lecturer won't help me with past exam paper answers.
How can more than one thread execute my oneTimeOnly() method? and what steps would i need to take to make it thread safe/only executed once by one thread?
public class ExampleClass {
private volatile boolean flag = false;
public void someOperation() {
if(flag != true) {
oneTimeOnly();
}
flag = true;
}
}
In a literal sense, nothing will prevent your method from being executed as many times as it is called. Only if understood on a higher level, the main logic of your method can be ensured to execute only once. I am saying this because some teachers/interviewers just love to nitpick and play meaningless mind games with their students/interviewees.
The problem with your approach is that two threads may be simultaneously executing your method, and setting flag to true only after both complete.
You can synchronize the method, or you can use an AtomicBoolean which can ensure that only one thread sets it to true. I believe this is too advanced for your class assignment, though, so stick with a syncronized method.
you should declare your method as synchronized:
public synchronized void someOperation() {
...
}
In this way you can be sure that only one thread at a time is executing your method's code, thus ensuring that the flag is set only once by the first thread calling it, and all other threads accessing it will find it already set.
Make the method synchronized or use synchronized block like
public void synchronized oneTimeOnly(){}

Strange behavior in Java with unsyncronized access in a multithreading program

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.

Categories

Resources