java threads effect on static classes - java

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.

Related

How to make a thread wait for a specific condition

There is a thread calculating prime numbers and adding them into a collection.
Now there are other Threads which will perform a bool isPrime(long n) method. This method will just look into the collection if it contains the number (n).
But the thread performing isPrime(...) needs to wait until:
the number was added
there is a number greater than n so I know n can't be prime.
And its only allowed to notify the thread in this cases. So I can't notify after every number added to the collection and check if its the number or higher.
Can you just give me some explanation about this waiting for conditions without busy waiting?
I just know that I can make threads wait on objects and other threads can notify them but i just cant get my head around this behavior, maybe I just think in a wrong way.
This really depends on your overall design.
A simple solution would work like this:
you have 1 thread prime-generator and n threads prime-testers
initially all prime-testers call wait()
every time prime-generator adds a new prime, it notifies all prime-testers
each testers checks if its number (or a larger one) is already in, if the tester either found its number, or knows "not in". If not, it calls wait() again.
The great advantage of that solution: the prime-generator doesn't need to know about how many prime-testers exist. It just notifies all threads waiting on a common monitor.
Alternatively, the prime-generator could know exactly which prime-testers exist, and also, what number they are responsible for. So instead of waking up all testers, it would notify only that one that needs to know.
Please understand: you only gave some vague requirements, without any code. Thus you receive a somehow vague answer, without any code. My answer is meant as inspiration to guide your next steps in your homework.
And just for the record: if you want to go for really large prime numbers, then using a list is a bad choice. Assume your list contains 1 million primes. The cost for calling contains() will grow linear with the number of entries. So rather use a collection that allows for quick finding of elements (some sort of set/tree), but also for quick access to the currently "last" (largest) number in the collection.
The basic idea from the answer by #GhostCat turned into code:
import java.util.HashSet;
import java.util.Set;
public class PrimeThreading {
// All prime numbers found so far.
private static final Set<Long> primes = new HashSet<>();
// Last number checked by the generator.
private static long numbersChecked = 0L;
// The lock object.
private static final Object lock = new Object();
private static class PrimeGenerator implements Runnable {
private final long maxNumber = Long.MAX_VALUE;
#Override
public void run() {
// Generate all prime numbers from 2 to maxNumber
for (long n = 2; n < maxNumber; n++) {
// Naively test if n is prime.
boolean isPrime = true;
for (long i = 2; i * i < n; i++) {
if (n % i == 0) {
isPrime = false;
break;
}
}
synchronized (lock) {
if (isPrime) {
primes.add(n);
}
numbersChecked = n;
// Notify waiting threads
lock.notifyAll();
}
}
}
}
private static boolean isPrime(long x) {
synchronized (lock) {
// Wait until number checked is greater than x
while (x > numbersChecked) {
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
return primes.contains(x);
}
}
public static void main(String[] args) {
Thread thread = new Thread(new PrimeGenerator());
thread.setDaemon(true);
thread.start();
System.out.println(isPrime(15_485_863));
}
}

Java - Why void when I'm storing value in variable

So, the question is. If I'm calling method guess from class - Player and it is a void-type method without return statement in it, how come I'm able to store result of number = (int)(Math.random() * 10) in number variable for 3 different objects (p1, p2, p3)?
I'm little confused about when should I use return statement or void-type methods, because if number = (int)(Math.random() * 10) is giving some results which I want to use, why then I don't need to return this results from a method to pass them to the number variable which I declared in int number = 0;
public class Player {
int number = 0;
public void guess() {
number = (int)(Math.random() * 10);
System.out.println("I'm guessing " + number);
}
}
A void method does not return anything, but it still allows you to do things. (Print to the console, modify variables etc) The void keyword just means that it doesn't return a value. (In void methods you can still use a blank return; to end the method) And because you are modifying your number variable in the GuessGame object the changes you make will stay even though you don't return a variable. Try this simple test to see what I mean:
//In your GuessGame class
int number = 0;
public void foo() {
number++;
}
public static void main(String[] args) {
GuessGames games = new GuessGames();
games.foo();
System.out.println(games.number);
//Outputs 1
}
docs for the return statement
The point is: where is the result of Math.random() * 10 physically stored on your computer when your program is run? You list two options.
Options 1: Instance field
In this case the compiler instructs your operating system to reserve space for a int variable for the whole life of the Player object. The player object may live for microseconds, seconds, minutes, hours, days, months, ... it depends! This storage space is usually find in the RAM of the computer and from Java you can access it with the syntax myPlayer.number as long as you have a Player reference somewhere.
Options 2: Return value
In this case the compiler finds the space to store the result of the computation in a register of the Java virtual machine, that you can mentally map to a register of the physical processor. This value will only at best survive for a couple of processor cycles (there are gazillinos in a GHz CPU, so it's really a tiny little fracion of a second) if you don't store it somewhere else - and if you don't it's lost forever. See the following example:
private int someRandom;
private int gimmeARandom() {
return Math.random() * 10;
}
private int test() {
int someRandom = gimmeARandom(); // --> store the value until end of method
this.someRandom = someRandom; // --> further keep it so we can read it later
gimmeARandom(); // --> what did it returned? We'll never know
}
Void is different than static - void just means the function does not return anything, but it can still be a instance method, i.e. one that is associated with each new instance of a class. I think you're confusing this with the functionality of static, which allows methods to be called without an instance of the class.

Data Races in an AtomicIntegerArray

In the code below:
I am updating num[1]=0 of an AtomicIntegerArray num 1000 times each in 2 threads.
At the end of the 2 threads in main thread ;shouldn't the value of num[1] be 2000 as there shouldn't be data races in an AtomicIntegerArray .
However I get random values < 2000. Could someone tell me why?
Code:
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArr {
private static AtomicIntegerArray num= new AtomicIntegerArray(2);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyRun1());
Thread t2 = new Thread(new MyRun2());
num.set(0, 10);
num.set(1, 0);
System.out.println("In Main num before:"+num.get(1));
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("In Main num after:"+num.get(1));
}
static class MyRun1 implements Runnable {
public void run() {
for (int i = 0; i < 1000; i++) {
num.set(1,num.get(1)+1);
}
}
}
static class MyRun2 implements Runnable {
public void run() {
for (int i = 0; i < 1000; i++) {
num.set(1,num.get(1)+1);
}
}
}
}
Edit: Adding num.compareAndSet(1, num.get(1), num.get(1)+1); instead of num.set(1,num.get(1)+1); doesnt work either.
I get random values < 2000. Could someone tell me why?
This is called the lost-update problem.
Because, in the following code:
num.set(1, num.get(1) + 1);
Although each individual operation involved is atomic, the combined operation is not. The single operations from the two threads can interleave, causing updates from one thread to be overwritten with stale value by another thread.
You can use compareAndSet to solve this problem, but you have to check whether the operation is successful, and do it again when it fails.
int v;
do {
v = num.get(1);
} while (!num.compareAndSet(1, v, v+1));
There's also a method for exactly this purpose:
num.accumulateAndGet(1, 1, (x, d)->x+d);
accumulateAndGet(int i, int x, IntBinaryOperator accumulatorFunction)
Atomically updates the element at index i with the results of applying the given function to the current and given values, returning the updated value. The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads. The function is applied with the current value at index i as its first argument, and the given update as the second argument.
This is a classic race condition. Any time you have a fetch, an operation, and a put, your code is racy.
Consider two threads, both executing num.set(1,num.get(1)+1) at roughly the "same time." First, let's break down what the expression itself is doing:
it fetches num.get(1); let's call this x
it adds 1 to that; let's call this y
it puts that sum in at `num.set(1, y);
Even though the intermediate values in your expression are just values on the stack, and not explicit variables, the operation is the same: get, add, put.
Okay, so back to our two threads. What if the operations are ordered like this?
inital state: n[1] = 5
Thread A | Thread B
========================
x = n[1] = 5 |
| x = n[1] = 5
| y = 5 + 1 = 6
y = 5 + 1 = 6 |
n[1] = 6 |
| n[1] = 6
Since both threads fetched the value before either thread put its added value, they both do the same thing. You have 5 + 1 twice, and the result is 6, not 7!
What you want is getAndIncrement(int idx), or one of the similar methods that does the get, adding, and putting atomically.
These methods can actually all be built on top of the compareAndSet method you identified. But to do that, you need to do the increment within a loop, trying until the compareAndSet returns true. Also, for that to work, you have store that initial num.get(1) value in a local variable, rather than fetching it a second time. In effect, this loop says "keep trying the get-add-put logic until it works without anyone else having raced between the operations." In my example above, Thread B would have noticed that compareAndSet(1, 5, 6) fails (since the actual value at that time is 6, not 5 as expected), and thus retried. This is in fact what all of those atomic methods, like getAndIncrement, do.

Two random walkers on a 2d plane

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.

Mutual exclusion code

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.

Categories

Resources