Java make wrong optimization - java

I have this code
while(!decks.get(0).isEmpty()){
SingleCardWindow obj = new SingleCardWindow(decks.get(0).take());
while(obj.isVisible()){
}
System.out.println("Closed");
}
SingleCardWindow it is inherit-class from JFrame. This code displays all cards from the deck. Displays one card, wait until I close this window, and displays next card. In Windows it works well.
In linux (java-oracle-7) "Closed" never writing!
But if I make
while(!decks.get(0).isEmpty()){
SingleCardWindow obj = new SingleCardWindow(decks.get(0).take());
while(obj.isVisible()){
System.out.println("SOMETHING");
}
System.out.println("Closed");
}
program works right. So, i think that compiler optimize "while(obj.isVisible())" like "while(true)". What I should do with this? I dont needs any code into the loop.

In the second case you added this line:
System.out.println("SOMETHING");
PrintStream#println is a synchronized method, so if that helped your program to start working, it is a quite clear indication that the method obj.isVisible is not synchronized, and since you don't use any explicit synchronization, you are effectively causing a data race in your program. The reading thread never observes the change in the value of the isVisible property.
But, as many others have already noticed, this just answers the question as you have asked it; the code you have posted has many more issues with an inappropriate programming model (busy waiting) used to solve an essentially event-based problem.

Related

If compareAndSet fails, is the code below still executed?

I have a very dumb question.
If I use AtomicReferences compareAndSet
this way
original.set(atomic.get());
long next = some new value
atomic.compareAndSet(original.get(), next);
....more code....
is more code still updated if the comparison fails (i.e. atomic has been updated by another thread).
I'm trying to find an error in an assignment and this is the only thing I can think about and I've been trying for few hours.
P.S.
Weirdly enough, if I use synchronize on this code
it gives me the correct answer on my laptop, but not on my desktop
MangatRaiModi and SotiriosDelimanolis put me on the right path.
A simple fix:
original.set(atomic.get());
long next = some new value
while(!atomic.compareAndSet(original.get(), next))
{
do above again
}
....more code....
did it.
Still not sure how synchronized fixed this on my laptop but not on my desktop.
I'm guessing that it's slowing the threads down on the mobile Chip enough so that they can operate sequentially (Like a Print statement).
I'm probably wrong though.

NullPointerException whilst learning concurrency in Scala

I'm having a little problem at the moment. My latest assignment is to create a rock paper scissors program which will run concurrently and output various values. Sounds simple and trivial, I know, but a little fun and I have been allowed to use scala which I had no knowledge of so thought it would be interesting.
Now the error is confusing me. I am receiving a NullPointerException on Thread 10, and have spent an awful long time trying to find it to no success. I have 6 classes so it would be impractical of me to put all of the code in, but I will put a few snippets.
result = Shapes.Winner(player1.getChoice(), player2.getChoice())
This is the line giving the error. Player1 and Player2 are simply objects from a class I have made, and they have been dequeued in.
Now for the confusing part. If I add a simple line in another class:
println(wait.getChoice())
it all works. This line has no relation to the first line above, and was simply for testing. But now when I take it out, I get the error. I would just leave it, but as you can see, it prints a load of rubbish onto the terminal.
I really have no idea what I'm doing wrong, and would love some help.
Feel free to ask for more snippets of the code, and thank you in advance for any help.
The problem is that you use synchronized incorrectly. You should wrap all calls to Referee.queue into Referee.synchronized {} blocks in order to synchronization to work. Otherwise the calls are not synchronized, and it's possible for one thread to modify Referee.queue without other thread notice.
Otherwise you should use thread safe collection. For example when I substitute scala.collection.mutable.Queue with scala.collection.mutable.SynchronizedQueue in the Referee class everything works ok, and you don't need to synchronize access to queue.
Even better use java.util.concurrent.ConcurrentLinkedQueue instead, because
SynchronizedQueue is deprecated in scala_2.11

In Java/Eclipse, why does setting a breakpoint in my code alter the effect of that statement?

I'm writing an Android app in Eclipse, and displaying some text on screen using a TextView. A different thread sometimes changes the text of this view, with the following code:
runOnUiThread(new Runnable() {
#Override
public void run() {
view.setText(newLyric);
}
});
I wanted to debug the setText line to check that the correct String was being passed in (as for some text, it was not being word-wrapped to fit the screen, and for other text it was, but that's a different issue). When I put a breakpoint on that line, the text is always word-wrapped. And when I disable/remove the breakpoint, the text that usually doesn't get word-wrapped (it's deterministic) is not word-wrapped.
This doesn't make much sense to me. I've seen this question, and I understand the reasoning behind that, but I can't see why that would be the issue here. Can anyone shed some light on this? I'm testing on a device, if that makes any difference.
Edit: It turns out it was a race condition, now I just have to work out how to fix it... Obviously I could only pick one 'correct' answer, but thank you to all of you for the helpful comments :)
Things like this are sometimes/often a sign of a race condition.
Putting a breakpoint eliminates the race (so a "rogue" thread that was overriding the value by running later is now finished by the time your breakpoint is caught, as an example).
Or it's a clear case of Heisenbug :)
Try setting setting the property Halt VM for your breakpoint. The default behaviour is to just halt the running thread. If you are getting "contamination" from other threads this should stop that from happening.
It is possible, since your code run in its own thread, that the code that sets up the screen (and hence, decides or not to wordwrap) would run before, or after your call, since it runs in another thread.
For example, in TextViews, events will fire off and be caught by OnEditorActionListener.

Weird Java problem, while loop termination

I have a piece of code that looks like this:
Algorithm a = null;
while(a == null)
{
a = grid.getAlgorithm();
}
getAlgorithm() in my Grid class returns some subtype of Algorithm depending on what the user chooses from some options.
My problem is that even after an algorithm is selected, the loop never terminates. However, that's not the tricky bit, if I simply place a System.out.println("Got here"); after my call to getAlgorithm(), the program runs perfectly fine and the loop terminates as intended.
My question is: why does adding that magic print statement suddenly make the loop terminate?
Moreover, this issue first came up when I started using my new laptop, I doubt that's related, but I figured it would be worth mentioning.
Edit: The program in question is NOT multithreaded. The code for getAlgorithm() is:
public Algorithm getAlgorithm ()
{
return algorithm;
}
Where algorithm is initially null, but will change value upon some user input.
I believe the issue has to deal with how grid.getAlgorithm is executed. If there is very little cost associated with executing the method, then your while loop will cycle very quickly as long the method continues to return null. That is often referred to as a busy wait.
Now it sounds like your new laptop is encountering a starvation issue which didn't manifest on your old computer. It is hard to say why but if you look at the link I included above, the Wikipedia article does indicate that busy waits do have unpredictable behavior. Maybe your old computer handles user IO better than your new laptop. Regardless, on your new laptop, that loop is taking resources away from whatever is handling your user IO hence it is starving the process that is responsible for breaking the loop.
You are doing active polling. This is a bad practice. You should at least let the polling thread sleep (with Thread.sleep). Since println does some io, it probably does just that. If your app is not multithreaded it is unlikely to work at all.
If this loop is to wait for user input in a GUI then ouch. Bad, bad idea and even with Thread.sleep() added I'd never recommend it. Instead, you most likely want to register an event listener on the component in question, and only have the validation code fire off when the contents change.
It's more than likely you're program is locking up because you've reached some form of deadlock more than anything else, especially if your application is multithreaded. Rather than try to solve this issue and hack your way round it, I'd seriously consider redesigning how this part of the application works.
You should check getAlgorithm(), there must be something wrong in the method.
There are two scenarios:
Your code is really not meant to be multi-threaded. In this case you need to insert some sort of user input in the loop. Otherwise you might as well leave it as Algorithm a = grid.getAlgorithm(); and prevent the infinite loop.
Your code is multi-threaded in which case you have some sort of 'visibility' problem. Go to Atomicity, Visibility and Ordering or read Java Concurrency in Practice to learn more about visibility. Essentially it means that without some sort of synchronization between threads, the thread you are looping in may never find out that the value has changed due to optimizations the JVM may perform.
You did not mention any context around how this code is run. If it is a console based application and you started from a 'main' function, you would know if there was multi-threading. I am assuming this is not the case since you say there is no multithreading. Another option would be that this is a swing application in which case you should read Multithreaded Swing Applications. It might be a web application in which case a similar case to swing might apply.
In any case you could always debug the application to see which thread is writing to the 'algorithm' variable, then see which thread is reading from it.
I hope this is helpful. In any case, you may find more help if you give a little more context in your question. Especially for a question with such an intriguing title as 'Weird Java problem, while loop termination'.

App hangs calling DefaultCellEditor constructor

I have control of a small piece of an application built on Eclipse, and I'm having a problem creating a DefaultCellEditor. The code actually uses a subclass of DefaultCellEditor, but I can recreate the problem using DefaultCellEditor, so that's what I'm going to ask about, hoping that it will solve the problem with the actual class. I've tried this with both JDK 1.5 and 1.6, and get the same behavior in both.
The problem happens when the constructor for DefaultCellEditor is called:
log.debug("Trying construction.");
currentCellEditor = new DefaultCellEditor(new JTextField());
log.debug("Constructed OK.");
When this code runs, maybe 20% of the time, the app hangs, and the CPU is pegged at 100% - looks like there's an infinite loop in there somewhere, but I don't know where. The first log line is printed, but the second is not.
I've tried making a copy of the DefaultCellEditor class and inserting System.out.println statements in there to see if I can figure out where the problem occurs; during the times that the code runs correctly, all of my debug statements are printed out, but when it doesn't run correctly, none of the statements are printed out, almost like the hang occurs before the constructor is called. Any ideas what could be happening?
Both of the comments on the question were helpful. I was able to use the thread dump and figure out what was causing the loop (I ended up using StackTrace). My other problem is that while I was on the EDT earlier on, at the point this code actually runs, it's not on the EDT anymore - so now I have to track that down, but some early testing indicates that putting this on the EDT may fix the problem. Thanks!

Categories