Looping in Threads - java

Consider the following two designs of run method:
Approach A
public void run() {
do {
//do something
} while (condition);
}
Approach B
public void run() {
//do something...
if (condition) {
new Thread(this).start();
}
}
The second approach seems cleaner to me, after some debate, I have been told it's not a good idea to use approach two.
Question:
What are reasons (if there is any) that I shouldn't be using approach 2?

You have two things here. A loop, and a method that continuously runs itself again in a new thread until a condition is met (not a loop).
If you need a loop, you would choose the standard normal loop that everyone understands and works perfectly.
If you need to write a weird piece of code that creates new threads for no reason, and makes other developers doubt your skills and understanding, you would go for option B.
There's absolutely no sense in your choice B unless there would be something additional like a queue or ThreadPoolExecutor involved for re-invoking the method, so the method would add this at the end for invocation at a later time, sort of like a "lazy loop".

Because approach B uses one more thread than approach A. Creating threads is expensive, for a number of reasons #see Why is creating a Thread said to be expensive?
Approach A is also a little clearer to the reader, IMO. The simplest option usually is.

The 2nd option creates a new thread every time it is iterated, so it ends up being unnecessarily costly, especially when option A does the same thing but doesn't create new threads for every iteration.

The only good use-case I can find for Pattern B is if there is a significant delay before you want to re-run the method. For example for some kind of polling system that is supposed to run every X minutes until the system is being shut down.
In that case, using a scheduler instead of a Thread.sleep(fiveMinutes) makes sense to avoid tieing up resources unnecessarily (maybe you are holding on to a database connections or such).
Note that in that case, you'd be using a scheduler, not just Thread#start, so I am allowing for a rather liberal interpretation of Pattern B.

They will behave very differently.
The first solution will loop until condition is false and then terminate.
The second solution will start a new thread and die until condition is false. It will likely accomplish what you want to do but it will waste a lot of resources allocating and destroying new threads.
Here's an example that loops over 5 values and prints the value and current thread name:
Loop:
Runnable loop = new Runnable() {
int i = 0;
#Override
public void run() {
do {
System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
i++;
} while(i < 5);
}
};
loop.run();
main: 0
main: 1
main: 2
main: 3
main: 4
Threaded:
Runnable thread = new Runnable() {
int i = 0;
#Override
public void run() {
System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
i++;
if(i < 5) {
new Thread(this).start();
}
}
};
thread.run();
main: 0
Thread-0: 1
Thread-1: 2
Thread-2: 3
Thread-3: 4
As you can see, the threaded example prints each line on a different thread which is very wasteful and probably not what you want to accomplish.

Related

Why does value not change inside thread?

When i assign a new value to variable it doesn't change after start(), however after i use join() it does. Why does this happen and in this case should int a be volatile or not?
class SampleThread extends Thread {
private static int a = 0;
#Override
public void run() {
a = 3;
}
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(new SampleThread());
t2.start();
System.out.println(a);
}
}
for seeing what is going on, try this:
...
#Override
public void run() {
System.out.println("start of Thread");
a = 3;
System.out.println("end of Thread");
}
...
only run method changed, rest of code unchanged
Yes, it needs volatile.
Every thread has an evil coin. The thread flips the coin anytime it reads or writes a field: Heads, and the thread uses its own local (to the thread) copy of it; if writing, that update simply does not reflect to all the other threads, who will still see the 'old' value, and if reading, same deal: Reads whatever it had, even though other threads updated it already. Even if they did so an hour ago. Tails, and it does refresh other threads' views of this thing, and won't use the local copy.
The coin is evil: it is not a fair coin. It will work every time today, and every time tomorrow, and every time during the test suite, and all throughout that week you have it live for the early adopting customers. And then juuust as that big client comes in and you're giving the demo? It flips to break your app every time. That kind of evil.
So, you must eliminate all coin flips, or at least ensure that the result of a coin flip does not affect your app whatsoever.
The way to do this, is to establish comes-before relationships. Between any 2 lines of java code as executed by a VM, there is a set of rules to determine if these 2 lines have such a relationship: That one is guaranteed to be run after the other. It's not about whether they did (timestamps of when they ran is completely irrelevant), it's whether the Java Memory Model decrees that such a relationship exists.
If yes, no coin is flipped: Anything the 'line that came before as per the JMM' did, is definitely visible to the line that came after. But if the JMM does not explicitly spell out that this relationship exists, the coin is flipped, and you lose.
One trivial 'comes before' relation ship is within a single thread: x = 5; System.out.println(x); trivially has such a relationship; they ran in the same thread, one came after the other. That's the freebie.
But between threads, oh dear. You need synchronized, volatile, or call code that does these things internally or has other mechanisms to ensure it (tip: There is lots of great stuff in the java.util.concurrent package, and as the name suggests, it's generally thread safe in very efficient ways. For example, an AtomicInteger is almost always far better than a volatile int, and can do far more, such as CAS operations, which volatile ints cannot do.
If you expect things in different threads to happen in a particular order -- in this case, that a = 2 is executed before `System.out.println(a)' -- then you have to write code to make that order happen.
In this trivial case, where no real work is being done, almost anything you can do makes the use of threads pointless. The main thread could 'join' the thread that's setting a to 2, but then all you've achieved is an expensive way to execute code that could be executed in a single thread.
main thread should wait that the other was executed
One solution is to use join()
class SampleThread extends Thread {
private static int a = 0;
#Override
public void run() {
a = 3;
}
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(new SampleThread());
t2.start();
// wait for completion of t2
t2.join()
System.out.println(a);
}
}

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

A simple Java Race Condition

I just wanted to write an example for an race condition:
MyParallelClass.java:
public class MyParallelClass implements java.lang.Runnable {
public int counter = 0;
#Override
public void run() {
if (test.globalVar > 0) {
for (int i = 0; i < 1000000; i++) {
counter++;
}
test.globalVar--;
}
}
}
test.java:
public class test {
public static int globalVar;
public static void main(String[] args) {
globalVar = 1;
MyParallelClass a = new MyParallelClass();
MyParallelClass b = new MyParallelClass();
new Thread(a).start(); // Thread A
new Thread(b).start(); // Thread B
System.out.println(globalVar);
}
}
What I thought would happen:
I thought this could output either 0 if thread A was executed completely before Thread B starts.
The variable test.globalVar could also get manipulated like this:
Thread A - Thread B
checks if (globalVar > 0)
looping ... checks if (globalVar > 0)
looping ... execute all four bytecode commands of "test.globalVar--;"
execute test.globalVar--;
so the value of test.globalVar would be -1.
So either one of the if-statements get executed or both.
What actually happened:
I got 0 and 1 as output of the main method. Why do I get 0 and 1 and not 0 and -1?
You are decrementing globalVar twice. The possible values of globalVar at the end are:
-1 - if everything went fine and both threads correctly decremented the value before it was printed
0:
if only one thread managed to decrement the variable and the second one didn't manage to finish before printing it
if the globalVar was decremented at the same time
1:
if System.out.println() managed to execute before both threads completed (quite probable). The globalVar was indeed modified, but after it was already printed
due to visibility issue main thread sees original globalVar value, not the one modified by different threads. You need some sort of synchronization or volatile keyword to see changes made by other threads immediately (or ever).
The
System.out.println(globalVar);
does not wait for the threads to complete. The threads may or may not be complete at that point. So the value can be 0, 1, or -1 depending on whether both the threads completed, one completed or both did not complete.
To have a better test,
- use Thread.sleep() in the threads to make sure that there is a delay
- Use different delays in the different threads to better visualize the race condition.
- You may want to print the value of the variable in the threads also. this way you have three threads racing (A, B and the main thread) and you get better visualizations.
Good question. I think you need to run more tests. :-)
You might try changing your loop in the Runnable class to sleep with a random number of milliseconds (500-1000). Loop just 10 times. See if you don't get your expected race condition.
I think that most computers are just too darn fast. You're simple loop may not be doing enough work to cause a thread switch.
I love these kinds of questions because I run into bugs like this all the time.
You can get a 1 if the value is printed before either thread has decremented the value.

Multithreading--Why one thread is doing all of the work?

I am multiplying two matrices using two threads (however, the program is written to scale up as well, so I could possibly use three, four, etc threads instead). Each thread calculates/does the work for one row (or column) of the final matrix. If one thread is doing work on a row, the other one(s) should not work on that row. It/they should move on to the next available row.
First of all, I am not certain if the way I implemented the problem is correct. If you can see a better way, please let me know.
Secondly, the way I have done it, every time I test it (with different size matrices--even huge ones), only one thread does the work. That is, each time, the same thread is getting access to the synchronized block of the run() method. The other threads are entering the run() method, but why is only one thread always gaining the lock and doing all of the work?
This is my run method:
public void run() {
System.out.println(Thread.currentThread().getName());
while (i < number of columns in final matrix) {
synchronized (this) {
if (i < number of columns in final matrix) {
for (int j = 0; j < Main.B[0].length; j++) {
for (int k = 0; k < Main.A[0].length; k++) {
Main.C[i][j] += Main.A[i][k] * Main.B[k][j];
}
}
i++;
}
}
}
}
This is the code in my driver class that creates the threads and starts the program:
MyRunnable r = new MyRunnable();
Thread thread1 = new Thread(r);
Thread thread2 = new Thread(r);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException ie) {
System.out.println("\nThe following error occurred: " + ie);
}
}
I guess my question is two-fold--is my approach correct for the problem at hand? If so, (and if not), why is one thread always grabbing the lock and doing all of the work? I have checked the program with up to 6 threads on 20x20 matrices and always only one thread is doing the work.
As some of the comments suggested, the problem is in the locking (i.e. the synchronized(this) part). Synchronizing is done on this which, in your case, a single instance of MyRunnable, so while one thread is doing the work inside the synchronized block, all other threads will wait until the work is finished. So effectively, only one thread is doing real work at a time.
Here's how to solve the problem. Since you need your threads to work on different rows in parallel, then this work must not be synchronized by a lock (because locking means the opposite: only one thread can do the work at a time). What you do need to synchronize is the part where each thread decides which row it will work on.
Here's a sample pseudo code:
public void run(){
int workRow;
synchronized(this){
workRow = findNextUnprosessedRow();
}
for(int i=0; i<matrix[workRow].length; i++){
//do the work
}
}
Note that the actual work is intentionally not synchronized, for reasons given above.
The way you are using threads is correct, so there is not problem with that, however, I would suggest you have a look at Java's concurrency API: Thread Pools. Here's an example of how to use it in your context:
//Creates a pool of 5 concurrent thread workers
ExecutorService es = Executores.newFixedThreadPool(5);
//List of results for each row computation task
List<Future<Void>> results = new ArrayList<Future<Void>>();
try{
for(int row=0; row<matrix.length; row++){
final int workRow = row;
//The main part. You can submit Callable or Runnable
// tasks to the ExecutorService, and it will run them
// for you in the number of threads you have allocated.
// If you put more than 5 tasks, they will just patiently
// wait for a task to finish and release a thread, then run.
Future<Void> task = es.submit(new Callable<Void>(){
#Override
public Void call(){
for(int col=0; col<matrix[workRow].length; col++){
//do something for each column of workRow
}
return null;
}
});
//Store the work task in the list.
results.add(task);
}
}finally{
//Make sure thread-pool is shutdown and all worker
//threads are released.
es.shutdown();
}
for(Future<Void> task : results){
try{
//This will wait for threads to finish.
// i.e. same as Thread.join()
task.get();
}catch(ExecutionException e){
//One of the tasks threw an exception!
throw new RuntimeException(e);
}
}
This approach is a lot cleaner, because the work distribution is done the main
thread (the outer for-loop), and therefore there is no need to synchronize it.
You also get few bonuses when working with thread pools:
It nicely takes care of any exceptions during the computations in each
of the threads. When working with bare threads, like in your approach, it is easy
to "lose" an exception.
Threads are pooled. That is, they get automatically reused so you don't need to worry about the cost of spawning new threads. This is particularly useful in your case, since you will need to spawn a thread per row in your matrix, which may be fairly large, I suspect.
Tasks submitted to ExecutorService are wrapped in a useful Future<Result> object, which is most useful when each computation task actually returns some kind of result. In your case, if you needed to sum-up all values in the matrix, then each computation task could return the sum for the row. Then you'd just need to sum up those up.
Got a bit long, but hope it clears some things up.
Your problem is that you synchronize the whole region with synchronized(this). This means that only one thread at a time is allowed to enter the loop doing the calculation. Of course it could mean that multiple threads can calculate different parts but never multiple threads at once. This also means your "parallel" solution it is not faster than one thread.
If you want to do the calculation in parallel have a look at Parallel Matrix Multiplication in Java 6 and Fork Join Matrix Multiplication in Java which should cover the topic
Thread scheduling depends on the particular VM implementation. In some implementations a thread will continue to run until it blocks in some way or is preempted by a higher priority thread. In your case all the threads have the same priority, so the first thread to enter the synchronized block never blocks, it does not get preempted. Some schedulers implement priority aging, such that a starved thread will eventually increase in priority, but you may not be running long enough for that to have an effect.
Add a Thread.yield() call just after the end of the synchronized block. This tells the scheduler to pick a new thread to run (maybe the same one, but probably a different one).
Your run function has the first thread to get the lock do all the work on a row while still owning the lock. For the next row, maybe another thread will get the lock, but it will block all other threads until it is done.
What I would do is have an array of booleans that is the same as the number of rows, and use these to claim the task of processing each individual row. It would be something like the following pseudocode:
//before creating the threads, pre-fill BoolList with trues
function run()
{
while (true)
{
lock(BoolList)
{
//find first true value and set it to false
//if no true found, return
}
//do the actual math of multiplying the row we claimed above
}
}
Also keep in mind that the overhead of creating a new thread is sufficient that multi-threading this program would only be worth it for large matrices.
As mru already stated in his comment, you problem is that all row calculation is performed inside "synchronized (this)" block. Because of this all threads will wait for one row to be processed before starting on next one, and same thread always acquiring the lock is probably the result of optimization, since you pretty much make calculations single-thread. You might consider putting only decision on which row to process inside the synchronized block:
int rowToProcess;
synchronized (this) {
if (i < number of columns in final matrix){
rowToProcess = i;
i++;
}
else
return;
}

Categories