So I have this multithreadded program that generates 2 random walkers, each walker is a separate thread since I need them to move simultaneously. Each walker randomly moves in any of the 4 directions. The first problem is that i think stdDraw is not thread safe and therefore without having a lock around my entire function, it tends to draw random squares at random points for no reason and the whole thing become pretty glitchy. When i put a lock around my function then one thread becomes slower that the other since it sometimes has to wait for the lock. So the threas are not simultaneous anymore. Is there a solution to this? The other problem i have is I want it to break out of the loop when the two walkers intersect, but for some reason the two threads dont know about the position of the other. One thinks that the position of the other is always at (0,0). Thanks!
import java.awt.Color;
public class WalkerThread implements Runnable {
String name;
static Integer lock = new Integer(1000);
int num;
static int steps = 0, steps2 = 0;
static int x = 0, y = 0;
static int x2 = -1, y2 = -2;
public WalkerThread(String s, int n) {
this.name = s;
this.num = n;
}
#Override
public void run() {
int N = 10;
StdDraw.create(600, 600);
StdDraw.setScale(-N, -N, +N, +N);
StdDraw.clear(Color.gray);
do {
synchronized (lock) {
if (num == 1) {
StdDraw.go(x, y);
StdDraw.setColor(Color.white);
StdDraw.spot(0.9, 0.9);
double r = Math.random();
if (r < 0.25)
x--;
else if (r < 0.50)
x++;
else if (r < 0.75)
y--;
else if (r < 1.00)
y++;
steps++;
StdDraw.setColor(Color.blue);
StdDraw.go(x, y);
StdDraw.spot(0.9, 0.9);
StdDraw.pause(40);
}
if (num == 2) {
StdDraw.go(x2, y2);
StdDraw.setColor(Color.yellow);
StdDraw.spot(0.9, 0.9);
double r2 = Math.random();
if (r2 < 0.25)
x2--;
else if (r2 < 0.50)
x2++;
else if (r2 < 0.75)
y2--;
else if (r2 < 1.00)
y2++;
steps2++;
StdDraw.setColor(Color.green);
StdDraw.go(x2, y2);
StdDraw.spot(0.9, 0.9);
StdDraw.pause(40);
}
}// lock
/*String pict = steps + ".png";
StdDraw.save(pict);*/
//if (posX == posX2 && posY == posY2) break;
} while ((Math.abs(x) < N && Math.abs(y) < N) && (Math.abs(x2) < N && Math.abs(y2) < N));
System.out.printf("Total steps of %s is %d and %d \n", name, steps, steps2);
}
}
//MAIN
public class Walkers{
public static void main(String[] args) {
Thread t1 = new Thread(new WalkerThread("one", 1));
Thread t2 = new Thread(new WalkerThread("two", 2));
t1.start();
t2.start();
}
}
Avoid Math.random() when going multi-threaded - create an r = new Random() in your Walker constructor, and use it as r.nextDouble().
Instead of the big if, take the differences between both branches (just a couple of colors) and place them in the constructor. Also, threads have separate namespaces. You don't need to keep x and x2 separate - each thread would have its own private x, invisible from the other thread. Your code could roughly end up 1/2 the size.
As far as synchronization goes, you have two problems. The first problem is that StdDraw is built on Swing (it runs in a JFrame, for example), which is not thread-safe. In particular, all drawing must happen in something called the event thread. This means that you should place all the drawing code within something like
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
synchronized (lock) {
// ... your calls to StdDraw here ...
}
}
});
However, this opens a big can of worms. First, the drawing code needs to access your data, which you will therefore want to prevent from changing at the same time. You can protect it with yet more synchronized (lock) { ... }, but that will mean that only one thread will be executing in any given moment. That's not what multithreading is for.
The simpler answer is, taking a peek at Elyasin's answer, to forget about parallel execution (it is really not needed here), and embrace turn-taking:
do {
bool turn = false;
// ... current init code here
if (turn) {
// ... current code for num==1
} else {
// ... current code for num==2
}
turn = !turn; // reverse turn for next round
} while (/* ... */);
No threads, no locks, no synchronization, and it should work smoothly and without artifacts.
So I have this multithreaded program that generates 2 random walkers,
each walker is a separate thread since I need them to move
simultaneously. Each walker randomly moves in any of the 4 directions.
You clearly state that you want two random walkers, any of the four directions is chosen randomly by any of the two walkers. So we stick to this requirement.
The first problem is that I think stdDraw is not thread safe and
therefore without having a lock around my entire function it tends to
draw random squares at random points for no reason and the whole thing
becomes pretty glitchy. When I put a lock around my function then one
thread becomes slower than the other one, since it sometimes has to wait
for the lock. So the threads are not simultaneous anymore. Is there a
solution to this?
Thread safety and randomness are not really correlated here. As clarified above you want the walkers to be random. This has nothing to with thread safety in the first place. Simply put: Thread safety means that if several threads share a data structure/address space, then access to it is guaranteed to be free of race conditions.
Not sure what you mean with random squares at random points for no reason. A lock is usually used to grant permissions to execute, or to grant access to one or more shared resources. Not sure why you use a lock here, I don't see a shared resource and I don't see why you use the lock to control thread execution one at a time if you don't want this in the first place.
The two random walkers are independent and the only shared resource I see is the 2D plane.
If you want the two walkers to execute simultaneously/concurrently then you should not use a lock the way you did I think.
I am not even sure if thread safety really is an issue here, maybe you don't need thread safety?
The other problem I have is I want it to break out of the loop when
the two walkers intersect, but for some reason the two threads don't
know about the positions of each other. One thinks that the position of
the other one is always at (0,0).
Oh, now that is a good follow up question. Maybe there is a shared resource then? Will it have to be thread safe then?
That is the 2D plane, which would know if the two walkers intersect or not? (I did not look into the StdDraw to be honest, but you would know to find out I think.) Find a way to get the two coordinates of the two random walkers from the StdDraw and check for intersection. If that is not possible then use a shared resource, i.e. a data structure that holds both coordinates of 1st random walker and 2nd random walker.
You would not need to care much about thread safety, because one random walker would only read (and not write) the values/coordinates of the other random walker.
Try that out and let us know.
Related
I have a question about concurrency, I just wrote a program that runs 2 threads with the following instructions:
Thread 1: increment by 1 the variable "num" till 1'000'000 with loop
Thread 2: same thing but decrementing
at the end I receive an undesired result. And yeah I know that I could synchronize or try to use reentrant locks, but the problem is that I can't understand what's behind all this different undesired results.
I mean the operations I'm using are commutative and hence we don't care about the ordering, so if this doesn't matter we should still obtain 0 which is not the case!
Can someone explain to me what happens behind all the computing, so that I can get a feel and I can recognize this situations immediately?
EDIT:
Since I was just interested in understanding the main concept I thought it wasn't necessary to put the code.
Code:
class MyThread implements Runnable {
int id;
volatile static long num = 0;
MyThread(int id) {
this.id = id;
public void run() {
if (id == 0) {
for (int j = 0; j < 100000; ++j)
num++;}
} else {
for (int j = 0; j < 100000; ++j)
num--;}
After this I create the Threads and run them:
MyThread p = new MyThread(0);
MyThread q = new MyThread(1);
Thread t = new Thread(p);
Thread u = new Thread(q);
t.start();
u.start();
try {
t.join();
u.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
EDIT2:
I understand the concept now, but I would also like to know why declaring the variable as volatile still gives me wrong results?
EDIT3: I thought about it, and I think it's because bad interleaving can still give problems!
If the increment/decrement operation are not atomic, you can end up with this kind of behaviors.
An operation is considered atomic if it appears to the rest of the system to occur instantaneously. (cf wikipedia).
Consider the following case:
Thread 1 reads the value n in the variable x.
Thread 2 reads the value n in the variable x.
Thread 1 increment the value and store it in the variable x, that now evaluate at n+1.
Thread 2 decrements the value and store it in the variable x, that now evaluate at n-1.
But what you wanted was the variable x to still evaluate at n.
I do not know the specific of java primitive but it appears that you could use AtomicInteger or using a synchronized method could solve your issue here.
just mark this field as volatile. By this way you will reach safe access and you will be able to change it in a multi-thread application without using any other synchronization tools.
I'm trying to convert this code to java and using thread to implement it
turn = 0 // shared control variable
while (turn != i);
// CS
turn = (turn + 1) % n;
I'm really tried hard to reach to right code but I failed this is my code
/*
* Mutual exclusion using thread
*/
class gV{
int turn=0;
}
class newThread extends Thread{
static int i;
int n=10;
newThread(gV obj){
this.i=obj.turn;
start();
}
public void run(){
while(obj.turn!=i&&obj.turn<n);
criticalSection(i);
obj.turn=(obj.turn+1);
i++;
}
public void criticalSection(int numOfProcess){
System.out.println("Process " + numOfProcess + " done!!");
}
}
class MutualExclusion{
public static void main(String args[]){
gV obj = new gV();
new newThread(obj);
}
}
I know my code has some mistakes. Thank you for the help!
Use an AtomicInteger.
Atomic means that any operation on it will fully complete before any other thread can see the result. Meaning that you won't have two simultaneous operations 'clobber' it. For example, imagine if you had a non atomic integer and two threads attempted to increment it simultaneously - say it had value 1, they both read it as 1 and attempt to set it to 2. They both incremented it once - but instead of it becoming 3, it became 2! AtomicInteger solves this problem by giving you IncrementAndGet, which guarantees no other thread can access the AtomicInteger's value before the increment completes.
In particular, use these methods:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#get()
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet()
You might notice that this increments it, but it doesn't take it modulo n. Well, you can take it modulo n whenever you read its value, you don't need it to be stored that way.
EDIT: By the way, doing something like this:
while (turn != i);
is called busy-waiting, and it's a bad idea because it means that CPU usage will be 100%, checking the variable hundreds of thousands of times per second. In this kind of scenario, instead of making each thread check as often as possible, you want to have threads wait and be notifyed by another thread when it is that thread's turn to continue execution.
I believe in Java that using lock and synchronized to implement mutual exclusion will also give you this property, e.g. if you try to lock on something or enter a synchronized block but it is already in use then the thread goes to sleep and is woken up when it is its turn. So, you can look into this as well.
consider the following code:
static class ThreadTest extends Thread {
int x;
int[] y;
public ThreadTest(int x, int[] y) {
this.x = x;
this.y = y;
}
#Override
public void run() {
while (x< 10) {
++x;
System.out.print("0");
}
while (y[0] < 10) {
++y[0];
System.out.print('1');
}
}
}
public static void main(String args[]) {
int x = 0;
int[] y = new int[1];
y[0] = 0;
Thread A = new ThreadTest(x, y);
Thread B = new ThreadTest(x, y);
B.start();
A.start();
}
how many 1's and how many 0's will be printed?
how can I ensure that the number of 1's will be the same every time the program runs?
notice that the class is static
How is it possible to evaluate the max and min appearances of "1"?
Currently, your code contains a race condition since the two threads are modifying the same y array. This means that the number of 1s that get printed is indeterminate.
how can I ensure that the number of 1's will be the same every time the program runs?
You need to introduce synchronization between the two threads.
This can be done in a variety of ways. The most common one in Java is to use a synchronized block around the code that modifies and/or reads shared state.
An alternative way is to replace the int[1] array with a single AtomicInteger. This would work pretty well for this particular case.
notice that the class is static
Whether the class is static is totally irrelevant here. All it means is that an instance of ThreadTest has no implicit reference to an instance of the outer class. It has nothing to do with the sharing of state between instances of ThreadTest (which I think is what you're implying here).
The min amount of 1s is obviously 10, the max amount will be 20.
20 because worst case will be that both threads reach
while (y[0] < 10)
at the same time every time, and then again reach
++y[0];
also at the same time every time, which will render one of the increments lost.
Whether or not the class is static does not play any role here.
While the ThreadTest.y variable is not static (and it shouldn't be), it is filled with a reference to the same array for all you threads. That is where your synchronization bug is: in main you should not be giving both threads the same array.
Just wondering if anyone would be able to take a look at this code for implementing the quicksort algorithm and answer me a few questions, please :-)
public class Run
{
/***************************************************************************
* Quicksort code from Sedgewick 7.1, 7.2.
**************************************************************************/
public static void quicksort(double[] a)
{
//shuffle(a); // to guard against worst-case
quicksort(a, 0, a.length - 1, 0);
}
static void quicksort(final double[] a, final int left, final int right, final int tdepth)
{
if (right <= left)
return;
final int i = partition(a, left, right);
if ((tdepth < 4) && ((i - left) > 1000))
{
final Thread t = new Thread()
{
public void run()
{
quicksort(a, left, i - 1, tdepth + 1);
}
};
t.start();
quicksort(a, i + 1, right, tdepth + 1);
try
{
t.join();
}
catch (InterruptedException e)
{
throw new RuntimeException("Cancelled", e);
}
} else
{
quicksort(a, left, i - 1, tdepth);
quicksort(a, i + 1, right, tdepth);
}
}
// partition a[left] to a[right], assumes left < right
private static int partition(double[] a, int left, int right)
{
int i = left - 1;
int j = right;
while (true)
{
while (less(a[++i], a[right]))
// find item on left to swap
; // a[right] acts as sentinel
while (less(a[right], a[--j]))
// find item on right to swap
if (j == left)
break; // don't go out-of-bounds
if (i >= j)
break; // check if pointers cross
exch(a, i, j); // swap two elements into place
}
exch(a, i, right); // swap with partition element
return i;
}
// is x < y ?
private static boolean less(double x, double y)
{
return (x < y);
}
// exchange a[i] and a[j]
private static void exch(double[] a, int i, int j)
{
double swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// shuffle the array a[]
private static void shuffle(double[] a)
{
int N = a.length;
for (int i = 0; i < N; i++)
{
int r = i + (int) (Math.random() * (N - i)); // between i and N-1
exch(a, i, r);
}
}
// test client
public static void main(String[] args)
{
int N = 5000000; // Integer.parseInt(args[0]);
// generate N random real numbers between 0 and 1
long start = System.currentTimeMillis();
double[] a = new double[N];
for (int i = 0; i < N; i++)
a[i] = Math.random();
long stop = System.currentTimeMillis();
double elapsed = (stop - start) / 1000.0;
System.out.println("Generating input: " + elapsed + " seconds");
// sort them
start = System.currentTimeMillis();
quicksort(a);
stop = System.currentTimeMillis();
elapsed = (stop - start) / 1000.0;
System.out.println("Quicksort: " + elapsed + " seconds");
}
}
My questions are:
What is the purpose of the variable tdepth?
Is this considered a "proper" implementation of a parallel quicksort? I ask becuase it doesn't use implements Runnable or extends Thread...
If it doesn't already, is it possible to modify this code to use multiple threads? By passing in the number of threads you want to use as a parameter, for example...?
Many thanks,
Brian
1. It's used to keep track of recursion depth. This is checked to decide whether to run in parallel. Notice how when the function runs in parallel it passes tdepth + 1 (which becomes tdepth in the called quicksort's parameters). This is a basic way of avoiding too many parallel threads.
2. Yes, it's definitely using another thread. The code:
new Thread()
{
public void run()
{
quicksort(a, left, i - 1, tdepth + 1);
}
};
creates an anonymous inner class (which extends Thread), which is then started.
Apparently, tdepth is used to avoid creating too many threads
It uses an anonymous class, which implicitly extends Thread
It does that already (see point 1.)
tdepth is there so that there's an upper bound on the number of threads created. Note that ever time the method calls itself recursively (which is done in a new thread), tdepth is incremented by one. This way, only the first four levels of recursion will create new threads, presumably to prevent overloading the OS with many threads for little benefit.
This code launches its own threads in the definition of the quicksort method, so it will use parallel processing. One might argue that it could do with some kind of thread management and that e.g. some kind of Executor might be better, but it is definitely parallel. See the call to new Thread() ... followed by start(). Incidentally, the call to t.join() will cause the current thread to wait for the thread t to finish, in case you weren't aware of that.
This code already uses multiple threads, but you can tweak how many it spawns given the comparison on tdepth; increasing or decreasing the value will determine how many levels of recursion create threads. You could complete rewrite the code to use executors and threadpools, or perhaps to perform trinary recursion instead of binary - but I suspect that in the sense you asked; no, there's no simple way to tweak the number of threads.
I did actually wrote a (correctly) multi-threaded QuickSort in Java so maybe I can help a bit...
Question here for anyone interested:
Multithreaded quicksort or mergesort
What is the purpose of the variable
tdepth?
as other have commented, it serves to determine whether to create new threads or not.
Is this considered a "proper"
implementation of a parallel
quicksort? I ask because it doesn't
use implements Runnable or extends
Thread...
I don't think it's that proper for several reasons: first you should make it CPU dependent. There's no point in spawning 16 threads on a CPU that has just one core: a mono-threaded QuickSort shall outperfom the multi-threaded one on a single core machine. On a 16-cores machines, sure, fire up to 16 threads.
Runtime.getRuntime().availableProcessors()
Then the second reason I really don't like it is that it is using last-century low-level Java idiosyncrasish threading details: I prefer to stay away from .join() and use higher level things (see fork/join in the other question or something like CountDownLatch'es, etc.). The problem with things low-level like Java's thread "join" is that it carries no useful meaning: this is 100% Java specific and can be replaced by higher-level threading facilities whose concept are portable across languages.
Then don't comment the shuffle at the beginning. Ever. I've seen dataset where QuickSort degrades quadratically if you remove that shuffle. And it's just an O(n) shuffle, that won't slow down your sort :)
If it doesn't already, is it possible
to modify this code to use multiple
threads? By passing in the number of
threads you want to use as a
parameter, for example...?
I'd try to write and/or reuse an implementation using higher-level concurrency facilities. See the advices in the question I asked here some time ago.
There are certain algorithms whose running time can decrease significantly when one divides up a task and gets each part done in parallel. One of these algorithms is merge sort, where a list is divided into infinitesimally smaller parts and then recombined in a sorted order. I decided to do an experiment to test whether or not I could I increase the speed of this sort by using multiple threads. I am running the following functions in Java on a Quad-Core Dell with Windows Vista.
One function (the control case) is simply recursive:
// x is an array of N elements in random order
public int[] mergeSort(int[] x) {
if (x.length == 1)
return x;
// Dividing the array in half
int[] a = new int[x.length/2];
int[] b = new int[x.length/2+((x.length%2 == 1)?1:0)];
for(int i = 0; i < x.length/2; i++)
a[i] = x[i];
for(int i = 0; i < x.length/2+((x.length%2 == 1)?1:0); i++)
b[i] = x[i+x.length/2];
// Sending them off to continue being divided
mergeSort(a);
mergeSort(b);
// Recombining the two arrays
int ia = 0, ib = 0, i = 0;
while(ia != a.length || ib != b.length) {
if (ia == a.length) {
x[i] = b[ib];
ib++;
}
else if (ib == b.length) {
x[i] = a[ia];
ia++;
}
else if (a[ia] < b[ib]) {
x[i] = a[ia];
ia++;
}
else {
x[i] = b[ib];
ib++;
}
i++;
}
return x;
}
The other is in the 'run' function of a class that extends thread, and recursively creates two new threads each time it is called:
public class Merger extends Thread
{
int[] x;
boolean finished;
public Merger(int[] x)
{
this.x = x;
}
public void run()
{
if (x.length == 1) {
finished = true;
return;
}
// Divide the array in half
int[] a = new int[x.length/2];
int[] b = new int[x.length/2+((x.length%2 == 1)?1:0)];
for(int i = 0; i < x.length/2; i++)
a[i] = x[i];
for(int i = 0; i < x.length/2+((x.length%2 == 1)?1:0); i++)
b[i] = x[i+x.length/2];
// Begin two threads to continue to divide the array
Merger ma = new Merger(a);
ma.run();
Merger mb = new Merger(b);
mb.run();
// Wait for the two other threads to finish
while(!ma.finished || !mb.finished) ;
// Recombine the two arrays
int ia = 0, ib = 0, i = 0;
while(ia != a.length || ib != b.length) {
if (ia == a.length) {
x[i] = b[ib];
ib++;
}
else if (ib == b.length) {
x[i] = a[ia];
ia++;
}
else if (a[ia] < b[ib]) {
x[i] = a[ia];
ia++;
}
else {
x[i] = b[ib];
ib++;
}
i++;
}
finished = true;
}
}
It turns out that function that does not use multithreading actually runs faster. Why? Does the operating system and the java virtual machine not "communicate" effectively enough to place the different threads on different cores? Or am I missing something obvious?
The problem is not multi-threading: I've written a correctly multi-threaded QuickSort in Java and it owns the default Java sort. I did this after witnessing a gigantic dataset being process and had only one core of a 16-cores machine working.
One of your issue (a huge one) is that you're busy looping:
// Wait for the two other threads to finish
while(!ma.finished || !mb.finished) ;
This is a HUGE no-no: it is called busy looping and you're destroying the perfs.
(Another issue is that your code is not spawning any new threads, as it has already been pointed out to you)
You need to use other way to synchronize: an example would be to use a CountDownLatch.
Another thing: there's no need to spawn two new threads when you divide the workload: spawn only one new thread, and do the other half in the current thread.
Also, you probably don't want to create more threads than there are cores availables.
See my question here (asking for a good Open Source multithreaded mergesort/quicksort/whatever). The one I'm using is proprietary, I can't paste it.
Multithreaded quicksort or mergesort
I haven't implemented Mergesort but QuickSort and I can tell you that there's no array copying going on.
What I do is this:
pick a pivot
exchange values as needed
have we reached the thread limit? (depending on the number of cores)
yes: sort first part in this thread
no: spawn a new thread
sort second part in current thread
wait for first part to finish if it's not done yet (using a CountDownLatch).
The code spawning a new thread and creating the CountDownLatch may look like this:
final CountDownLatch cdl = new CountDownLatch( 1 );
final Thread t = new Thread( new Runnable() {
public void run() {
quicksort(a, i+1, r );
cdl.countDown();
}
} };
The advantage of using synchronization facilities like the CountDownLatch is that it is very efficient and that your not wasting time dealing with low-level Java synchronization idiosynchrasies.
In your case, the "split" may look like this (untested, it is just to give an idea):
if ( threads.getAndIncrement() < 4 ) {
final CountDownLatch innerLatch = new CountDownLatch( 1 );
final Thread t = new Merger( innerLatch, b );
t.start();
mergeSort( a );
while ( innerLatch.getCount() > 0 ) {
try {
innerLatch.await( 1000, TimeUnit.SECONDS );
} catch ( InterruptedException e ) {
// Up to you to decide what to do here
}
}
} else {
mergeSort( a );
mergeSort( b );
}
(don't forget to "countdown" the latch when each merge is done)
Where you'd replace the number of threads (up to 4 here) by the number of available cores. You may use the following (once, say to initialize some static variable at the beginning of your program: the number of cores is unlikely to change [unless you're on a machine allowing CPU hotswapping like some Sun systems allows]):
Runtime.getRuntime().availableProcessors()
As others said; This code isn't going to work because it starts no new threads. You need to call the start() method instead of the run() method to create new threads. It also has concurrency errors: the checks on the finished variable are not thread safe.
Concurrent programming can be pretty difficult if you do not understand the basics. You might read the book Java Concurrency in Practice by Brian Goetz. It explains the basics and explains constructs (such as Latch, etc) to ease building concurrent programs.
The overhead cost of synchronization may be comparatively large and prevent many optimizations.
Furthermore you are creating way too many threads.
The other is in the 'run' function of a class that extends thread, and recursively creates two new threads each time it is called.
You would be better off with a fixed number of threads, suggestively 4 on a quad core. This could be realized with a thread pool (tutorial) and the pattern would be "bag of tasks". But perhaps it would be better yet, to initially divide the task into four equally large tasks and do "single-threaded" sorting on those tasks. This would then utilize the caches a lot better.
Instead of having a "busy-loop" waiting for the threads to finish (stealing cpu-cycles) you should have a look at Thread.join().
How many elements in the array you have to do sort? If there are too few elements, the time of sync and CPU switching will over the time you save for dividing the job for paralleling