Confused about how I should handle my looping thread - java

I'm currently confused on how I should solve a certain problem:
I have a thread, whose run() method approximately looks like this:
#Override
public void run() {
running = true;
while(running) {
foo(x);
draw(x);
}
}
Now this foo does something with variable x.
In the main thread theres a listener executing a method, which also changes x
#Override
public void mouseDragged(MouseEvent e) {
bar(x);
}
The problem is now, that sometimes x gets modified by the bar(x) method, while foo(x) also changes x, which messes x up.
What I think could be done to fix this is for the listener, when firing, to wait for the loop to reach its end, execute its method and bar(x) while letting the thread wait and then notify the thread to let it continue looping after that.
I'm not very experienced with thread-handling though and would appreciate it, if someone helped me out. Sorry if this problem is really easy to solve and I just can't see the solution.

You should make x an AtomicInteger (a thread-safe wrapper for Integers) and use it's methods to update and retrieve it in bar(), foo(), and draw().
Some of the key methods here are incrementAndGet() (like ++x), getAndIncrement() (like x++). More here at the JavaDocs:
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html
Java 8 added a whole lot more to that interface for atomically doing larger calculations as well.
AtomicInteger may not be the correct type. I'm guessing it based on guessing that x is an int in your example.

Nevermind guys, I just had to synchronize the methods of x, which got called by the loop and the listener.
I should've represented the accessing of x by saying x.foo() and x.bar(), sorry for the unclear question.

Related

Wait for method to Finish, and weird interaction with System.println

I am trying to write a genetic program to play through a game, but I am running into a bit of a snag. When I call this code:
public double playMap (GameBoard gb, Player p) {
gb.playerController = p;
Game g = new Game(gb);
int initHP = 0;
for (Unit u : gb.enemy.units) {
initHP += u.maxHP;
}
g.playGame(false);
int finalHP = 0;
for (Unit u : gb.enemy.units) {
finalHP += u.currHP;
}
System.out.println(" " + initHP);
System.out.println(" " + finalHP);
System.out.println(" " + (finalHP - initHP));
if (initHP == finalHP) {
return -10;
}
return initHP - finalHP;
}
the g.playGame() line does not have time to finish, and I am getting incorrect results from the function. I can wait out unit the game is over with a
while (!g.isDone) {
System.out.println(g.isDone);
}
but not with the same while loop without a print statement. I know there has to be a more elegant solution, and I cant seem to implement the methods I have seen. Also if anyone knows why I need the print statement in the while loop to get it to wait that would be great too.
Thanks in advance.
ADDED playGame:
public void playGame(boolean visual) {
Global.visual = visual;
if (Global.visual) {
JFrame application = new JFrame();
application.setBackground(Color.DARK_GRAY);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(this);
application.setSize(500, 400); // window is 500 pixels wide, 400 high
application.setVisible(true);
}
PlayerInput pi = new PlayerInput();
this.addKeyListener(pi);
final Timer timer = new Timer(10/60, null);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pi.addPressed();
if (update(pi)) {
// application.setVisible(false);
// application.dispose();
System.out.println(gb.toString());
isDone = true;
timer.stop();
}
pi.reset();
}
};
timer.addActionListener(listener);
timer.start();
while (!isDone) {
System.out.println(isDone);
}
}
First of all, this is a really bad way of doing this. This approach is called "busy waiting" and it is very inefficient.
The problem is most likely that reads and writes to g.isDone are not properly synchronized. As a consequence, there are no guarantees that the "waiting" thread will ever see the update to g.isDone that sets it to true.
There are various ways to ensure that the update is seen. The simplest one is to declare isDone as volatile. Another one is to do the reads and writes within a primitive lock.
The reason that the println() call "fixes" things is that println is doing some synchronization behind the scenes, and this is leading to serendipitous cache flushing (or something) that makes your update visible. (In other words: you got lucky, but exactly how you got lucky is hard to tie down.)
A better solution is to use another mechanism for coordinating the two threads.
You could use Thread.join() so that one thread waits for the other one to terminate (completely!).
You could use a Latch or Semaphore or similar to implement the waiting.
You could use an Executor that delivers a Future and then call Future.get() to wait for that to deliver its result.
You could even use Object.wait and Object.notify ... though that is low-level and easy to get wrong.
Without seeing the full context, it is hard to judge which approach would be most appropriate. But they would all be better than busy-waiting.
Another answer says this:
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.
As I explained above, the real problem is inadequate synchronization. To be technical, there needs to be a happens-before relationship between the write of isDone in one thread and the read of isDone in the other one. Various things will give that ... but without that, the compiler is entitled to assume that:
the writing thread does not need to flush the write to memory
the reading thread does not need to check that the memory has changed.
For example, without the happens-before, the compiler would be permitted to optimize
while (!g.isDone) {
// do nothing
}
to
if (!g.isDone) {
// do nothing
}
We don't know if this actually happens, or whether the actual cause of "non-visibility" of the update to isDone is something else. (Indeed, it could be JVM version / platform specific. To be sure, you would need to get the JIT compiler to dump the native code for the methods, and analyze the code very carefully.)
Apparently you are running your game in a separate thread. Assuming that thread is called foo, calling foo.join() will block the calling thread until foo finishes executing. You can simply replace your entire loop with foo.join().
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.

Java - terminating a method within a Thread

I have a Java thread with a run method that computes many things. You can think of it as a series of math statements as follows. Note that each computation may utilize other methods that in turn might have additional loops and such.
public void run() {
[computation 1 goes here here that takes a few seconds]
[computation 2 goes here that takes a few seconds]
....
[computation 30 goes here that takes a few seconds]
}
There is a GUI that prints the output of these statements as they produce their results, and I'd like the user to be able to say "Stop" whenever they want. Here are two methods I thought of
Method 1: Many Boolean Checks [LOOKS TERRIBLE]
private boolean stop;
public void run() {
if(!stop)
[computation 1 goes here here that takes a few seconds]
if(!stop)
[computation 2 goes here that takes a few seconds]
....
if(!stop)
[computation 30 goes here that takes a few seconds]
}
In this method, once the stop flag has been set to true, the computations will end. Note how silly this looks, having 30 if statements. Importantly, the critical question here is how often to put these conditions. Note that the computations on each line are not necessarily a single line. Taken to the extreme, does EVERY line in the run() method deserve a if(!stop) call above it? This doesn't seem like good design.
Method 2: Generalizing Computations [CANNOT DO THIS]
pirivate boolean stop;
public void run() {
for(int i = 0; i < computationsN && !stop; i++) {
computuations.get(i).compute();
}
I imagine that this method will be suggested, so I'd like to simply state that it is impossible in my case, given the sheer variation in the lines that I am calling "computations" for simplicity. I have typically done this for threads that are basic while loops, and it works great for such. But not in this case when the run() method is simply a huge method of variable code.
Any other solutions out there? Seems like this should be a universal problem. Thanks in advance!
what you want to do actually could be done with method 2, but you have to use the Strategy Pattern, is really the one more thing you need, because it make it possible to simplify your computations in one single line, like you actually did in Method 2.
It works like this, it lets you to change the next executable algorithm by doing polymorphism.
So first you have to make all your algorithms in different classes and each one has to implement one interface (it could be called Computable ) with one single method, that is, your compute() method.
Ex.
public interface Computable {
public void compute();
}
And your Algorithms classes could be something like:
public class AlgorithmX implements Computable {
#Override
public void compute() {
// TODO Your Real Computation here for the Algorithm X
}
}
Then in your for Loop your computations Collection (or Array) is populated with Objects that implements Computable, i.e., with your Algorithms Objects.
for(int i = 0; i < computations && !stop; i++) {
computuations.get(i).compute();
}
So you are in the right path with Method 2, I hope your way is more clear now.
Cheers!
Instead of using a stop flag you can call interrupt() on the thread to halt it, and inside your run method check to see if (Thread.interrupted()) is true (interrupt() doesn't immediately halt the thread, you've still got to check for Thread.interrupted()). This way you avoid pitfalls like forgetting to declare your flag as volatile.
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#interrupt%28%29
Short of encapsulating all of your computations in Runnables then putting them in an array and looping over them, which you've ruled out, Method 1 is your best bet. As for how often you should check to see if your thread is interrupted, that depends on how long it takes your computations to run and how responsive you want your program to be to a Stop command - you can add several println(System.currentTimeMillis) statements to get an idea of the computations' timing, then add an if(Thread.interrupted()) return; every 500 milliseconds or so to halt the run method.
I wouldn't immediately rule out Method 2, however, as your computations don't need to have anything in common in order for you to put them in Runnables
private ArrayList<Runnable> runnables = new ArrayList<>();
runnables.add(new Runnable() {
public void run() {
// computation 1
}
})
runnables.add(new Runnable() {
public void run() {
// computation 2
}
})
// etc
public void run() {
for(Runnable runnable: runnables) {
if(Thread.interrupted()) return;
runnable.run();
}
}
Depending on how your GUI is structured, is there any chance that you could throw an exception (probably an interruptedexception) from the GUI code that would blow out the long process?
The key thing is to look for somewhere in your code flow where things bottleneck to a point where a check could be inserted. This may not be super obvious (for example, you could hook the repaint manager in a swing app) - and it is definitely not good practice in the general case - but for a very specific use-case, it may be appropriate.
If that's not possible, a slightly less verbose approach would be to use a method like this:
assertContinue() throws InterruptedException;
(or maybe call it ac() to keep the typing down).
you still wind up with cruft in your algorithm, but at least it's less typing.
Oh - and what are these calculations? Are they blocking b/c of IO or locks somehow? If so, then calling Thread.interrupt() will work...

Are unresettable "flags" threadsafe in Java?

I have been using this pattern for a while, but I only recently came to think that it might not be OK to do this. Basically, I use some variant of this pattern:
public class SampleJavaAsync
{
public SampleJavaAsync() { }
private boolean completed;
public void start()
{
new Thread(new Runnable() {
#Override
public void run() {
//... do something on a different thread
completed = true;
}
}).start();
}
public void update()
{
if (!completed) return;
//... do something else
}
}
*The user is responsible for making sure start is only called once. update is called wherever and whenever.
I've always assumed this is threadsafe in Java, because even though nothing is strictly synchronized, I only ever set completed to true. Once it has been observed to be true, it will not reset to false. It is initialized to false in the constructor, which is by definition thread safe (unless you do something stupid in it). So, is it thread safe to use unresettable flags in this way? (And if so, does it even provide any performance benefits?)
Thanks
Java: it's feasible for update() to not see the update to completed that has already happened. Unless you mark it volatile, the JVM is permitted to do all sorts of things in the name of optimization (namely reordering reads and writes as it sees fit), meaning you could feasibly hit a state where the thread running update() NEVER sees that completed has changed, because it's not marked volatile, and it thinks it can optimize away that pesky write (or defer it).
You would at least run the risk of having inconsistency when it's first set, where, e.g. a call to update() on the same thread could see a different value than the same call from another thread, at the same time.
Better explained:
http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html
Or, if you're really curious about concurrency in Java, buy a copy of JCIP:
http://jcip.net.s3-website-us-east-1.amazonaws.com/

semaphores in java

Has anyone got any idea how to implement a rudimentary semaphore in java without making use of wait(), notify() or synchronize.I am not looking for a solution to this problem just a pointer in the right direction because I amd totally lost on this.
java.util.concurrent.Semaphore
I had similar homework few years ago at my university, but in C++. Java is too high level language for this kind of stuff.
Here is my implementation of signal and wait in C++, but I don't know if it is going to be helpful because you will have to implement a lot of other things.
int KernelSem::wait() {
lock();
if(--value < 0) {
PCB::running->state = PCB::BLOCKED;
PCB::running->waitingAtSem = this;
blockedQueue->put(PCB::running);
dispatch();
}
else {
PCB::running->deblockedBy = 0;
if(semPreempt) dispatch();
}
unlock();
return PCB::running->deblockedBy;
}
void KernelSem::signal() {
lock();
if(value++ < 0) {
PCB* tempPCB = blockedQueue->get();
if(tempPCB) {
tempPCB->state = PCB::READY;
tempPCB->deblockedBy = 0;
tempPCB->waitingAtSem = 0;
Scheduler::put(tempPCB);
}
}
if(semPreempt) dispatch();
unlock();
}
lock and unlock functions are just asm{cli} and asm{sti} (clear/set interrupt flag).
PCB is a process control block.
Hope it helps
in a very simple simple (again) simple way you could implement this using a simple int or boolean.
Test the int or boolean before grant acess. If it is 0 (tired of boolean), add 1 and continue. If not do Thread.yield() and try again latter. When you release, remove 1 from int and continue.
naive implementation, but works fine.
I hope that this is homework, because I cannot see any good reason you might want to do this in production code. Wikipedia has a list of algorithms for implementing semaphores in software.
Doing as proposed in the accepted answer will lead to a lot of concurrent issues as you can't ensure mutual exclusion with this. As an example, two threads asking to increment an integer would both read the boolean (that is proposed as lock) the same time, then both will think it's ok and then both set the bool to its opposite value. Both threads will go in changing stuff and when they are done they will both write a value to the (non)mutually exclusive variable and the whole purpose of the semaphore is lost. The wait() method is for waiting until something happen, and that's exactly what you want to do.
If you absolutely don't want to use wait, then implement some kind of double checking sleep technique where the thread first check the lock variable, changes it to false and sets a flag in an array or something with a special slot just for that thread to ensure that it will always succeed. Then the thread can sleep for a small interval of time and then checks the whole array for more flags to see if someone else were at it the same time. If not, it can continue, else it can't continue and have to sleep for a random amount of time before trying again (to make the threads sleep for lengths to make someone success later). If they collapse again then they will sleep for an even longer random time. This technique is also used in networks where semaphores cannot be used.
(Of course semaphores is exactly what you want to do but as it uses wait i kind of assumed you wanted something that don't use wait at all...)

Simple thread problem in java

Works except for when I free the crawler:
public void setCrawlerFree(WebCrawler w)
{
synchronized(myFreeCrawlers)
{
synchronized(numToGo)
{
myFreeCrawlers.add(w);
myFreeCrawlers.notifyAll();
numToGo--;
numToGo.notify();
}
}
}
When the crawler is done, I can add it back on the list. I also want to subtract 1 from the number of things I still need to do. I have one main thread waiting until numToGo is at 0. I'm getting an IllegalMonitorStateException on numToGo.notify() but since its inside of the synchronization block, doesn't that mean I own it?
Consider rewriting it to ExecutorService.
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize, keepAliveTime, timeUnit,
new LinkedBlockingQueue<Runnable>());
executor.submit(new Callable<...>() { ... });
It would greatly simplify your code and eliminate thread synchronization issues.
So I thought I needed to call wait and
notify on the object that all the
threads have in common, but that's not
correct either.
Yes, it is. But:
public class IllegalMonitorStateException
extends RuntimeException
Thrown to indicate that a thread has
attempted to wait on an object's
monitor or to notify other threads
waiting on an object's monitor without
owning the specified monitor.
You need to synchronize on an object before calling wait() or notify() on it.
Is your numToGo field is a primitive type which is being wrapped ? (int to Integer, long to Long, etc). Remember these wrappers are immutable and will cause you to have different object every time the boxing/unboxing happens. It's always recommended to use final objects when synchronization is needed.
Instead of using and integer create your own object to maintain the value and synchronization.
class Counter {
private int value ;
private final Object lock = new Object() ;
public ExecutionStatus() { }
public void increment() {
synchronized(lock) {
value ++ ;
}
}
public void decrease() {
synchronized(lock) {
value-- ;
}
}
// Read dirty
public int count() {
return value ;
}
public int safeCount() {
synchronize(lock) {
return count() ;
}
}
}
Never the less, you can add the line private final Object lock = new Object() to your current code and use that to control the synchronization of the numToGo variable.
Hope this helps.
you are synchronising on a non-final member variable. Your sync(numToGo) syncs on some value of numToGo and then you change the reference: numToGo--. You now have a different instance on which you call notify, hence the exception.
Some good posts there, there are plenty of alternatives but I imagine this is some kind of academic exercise? As people have pointed out, you'd probably wouldn't use wait/notify/notifyAll when there are more modern alternatives that makes things easier. The wait/notify thing though is interesting and is well worth understanding as a basis for concurrency work.
I'm assuming this is some kind of consumer/producer thing? One thread is trapping a crawler, the other setting it free? If that's the case, you might want to wait for the trap to have occupants before setting free? it might look something like this...
private final List<Object> trap = new ArrayList<Object>();
public class BugCatcher {
public void trapCrawler(Object crawler) {
synchronized (trap) {
trap.add(crawler);
System.out.println("caught bug number " + trap.size() + "!");
trap.notifyAll();
}
}
}
public class Hippy {
public void setCrawlerFree(Object crawler) throws InterruptedException {
synchronized (trap) {
trap.wait();
trap.clear();
System.out.println("set bugs free! time to hug a tree");
}
}
}
If the BugCatcher can catch bugs quicker than the hippy releases them, the hippy waits for the trap to have something in it before attempting to release the bugs (hence the wait call).
If you leave out the wait/notify part, things will rely just on the synchronized keyword, only one thread will access the trap at a time and its a race as to which gets there first (the hippy might try an empty an already empty trap).
In order to co-ordinate the wait and notify, the VM will use an object monitor. A thread acquires the object's monitor when it enters a synchronized block. An object has just a single monitor which acts as a mutually exclusivity lock (mutex). If you try and wait or notify without first getting the object's monitor (without executing wait or notify within a synchronized block), the VM can't set things up and so throws the IllegalMonitorException. It's saying "I can't allow this because if, for example, I wait, when will I know that I can progress when somebody calls notify? what/who are they notifying?". It uses the monitor to coordinate and so forces you to acquire the monitor.
So, the error you get is because numToGo isn't syncrhonised in the other thread (as Michael said previously).
I can't quite see why you need the numToGo, if it is producer/consumer, do you want to stop after a certain number? After the bug catcher catches 10 bugs and the hippy releases 10? Doesn't sound like that's what you're trying to do (as they could both have unrelated internal counters), so I'm not sure what you trying to do there. It'd be good to outline what you're trying to do in case I've gone off on completely the wrong tangent!

Categories