I have 2 questions:
1. why run() is not called when I run the program
2. if run() is called, will it change the value of randomScore?
import java.*;
public class StudentThread extends Thread {
int ID;
public static volatile int randomScore; //will it change the value of randomScore defined here?
StudentThread(int i) {
ID = i;
}
public void run() {
randomScore = (int)( Math.random()*1000);
}
public static void main(String args[]) throws Exception {
for (int i = 1;i< 10 ;i++)
{
StudentThread student = new StudentThread(5);
student.start();
System.out.println(randomScore);
}
}
}
Most importantly, you need to change
randomScore = (int) Math.random() * 1000;
to
randomScore = (int) (Math.random() * 1000);
^ ^
since (int) Math.random() always will equal 0.
Another important thing to notice is that main thread continues and prints the value of randomScore without waiting for the other thread to modify the value. Try adding a Thread.sleep(100); after the start, or student.join() to wait for the student thread to finish.
You should also be aware of the fact that the Java memory model allows for threads to cache their values for variables. It may be that the main thread has cached it's own value.
Try making the randomScore volatile:
public static volatile int randomScore;
Your run method is called but you're not waiting for it to complete. Add student.join() after the student.start()
If the run() method is called then it will change value of the randomScore variable but you should do like #aioobe suggests to make these changes visible.
It will change the value, but your reading of the value may happen before the code has executed to set it. It is executing in another thread, after all.
If you want to guarantee the variable being set before reading, you could use a CountdownLatch (create a latch of 1 and countdown after setting the variable, in the other thread use latch.await()), or alternatively use Thread.join() to wait for the thread to finish execution.
Yeah, the run method is being called. But it may be too quick. You can either join the thread with main thread and wait for a while.
The real problem in your code is that you cast Math.random as int before you multiply it by 1000.
randomScore = (int) (Math.random()*1000);
While your code executes the following happens
You set random score to zero (inital state)
When you want to change the random score
Math.random creates a double value that is equal to or greater than 0 and less than 1
You cast the double to an int which is always 0
You multiply 0 by 1000 that gives you a random score of 0.
The rest of the answers gives you reasons why your code is not thread safe.
TL;DR:
The run() method is called in your program
No, it will not as there's a bug in the random scoring algorithm. Actually, random score is always set to 0 on every execution of the run method.
Related
public class Bank {
private int sum=0;
public void add(int n) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
sum+= n;
System.out.println(sum);
}
}
public class Consumer implements Runnable {
Bank bank = new Bank();
#Override
public void run() {
for (int i = 0; i < 10; i++) {
bank.add(100);
}
}
}
public class Tes2 {
public static void main(String[] args) {
Consumer consumer = new Consumer();
Thread thread1 = new Thread(consumer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
}
}
This is a multithreaded program, simulation is multiple depositors to the bank to deposit money, used to demonstrate multithreaded security issues.Since the code is not synchronized, its first and second results might be 200/200,200/300, and so on.But I don't understand why you get 100/100, who can explain?
This is a race condition.
Both threads have access to sum.
sum += n; is not atomic
Thread 1 reads sum 0
Thread 2 swaps in because the code isnt synchronized reads sum as 0
Thread 1 adds 100 to 0 and writes that to sum
Thread 2 adds 100 to 0 and writes that to sum overwriting thread 1s value
If you think about the concurrency of this program just based on the lines in the code, the 100/100 output result wouldn't make sense. But you also have to think about what instructions are actually happening when these lines are being performed. Each line of code can consist of many, many assembly instructions. In this case, to add n to sum, what really happens is that the value of sum is read from memory, probably loaded onto a register, incremented, then re-written onto memory.
The 100/100 output can happen in the following scenario. Let's say thread 1 and thread 2 both call bank.add(100), and the bank handles requests asynchronously. That is, the bank has a thread handling each request.
Then, thread 1 of the bank loads the value of sum, which is zero. Thread 2 also loads the value of sum right after, which is still zero. Then, thread 1 takes the value it loaded, adds n=100, and writes it into memory. Thread 2 does the same; it takes the value of sum it loaded previously, 0, adds 100, then writes it back onto memory. Then, they each print out the value of 100.
I have recently begun to learn CodaHale/DropWizard metrics library. I cannot understand how is the Meter class thread-safe (it is according to the documentation), especially mark() and tickIfNecessary() methods here:
https://github.com/dropwizard/metrics/blob/3.2-development/metrics-core/src/main/java/com/codahale/metrics/Meter.java#L54-L77
public void mark(long n) {
tickIfNecessary();
count.add(n);
m1Rate.update(n);
m5Rate.update(n);
m15Rate.update(n);
}
private void tickIfNecessary() {
final long oldTick = lastTick.get();
final long newTick = clock.getTick();
final long age = newTick - oldTick;
if (age > TICK_INTERVAL) {
final long newIntervalStartTick = newTick - age % TICK_INTERVAL;
if (lastTick.compareAndSet(oldTick, newIntervalStartTick)) {
final long requiredTicks = age / TICK_INTERVAL;
for (long i = 0; i < requiredTicks; i++) {
m1Rate.tick();
m5Rate.tick();
m15Rate.tick();
}
}
}
}
I can see that there is a lastTick of type AtomicLong, but still there can be a situation that m1-m15 rates are ticking a little bit longer so another thread can invoke those ticks as well as a part of next TICK_INTERVAL. Wouldn't that be a race condition since tick() method of Rates is not synchronized at all? https://github.com/dropwizard/metrics/blob/3.2-development/metrics-core/src/main/java/com/codahale/metrics/EWMA.java#L86-L95
public void tick() {
final long count = uncounted.sumThenReset();
final double instantRate = count / interval;
if (initialized) {
rate += (alpha * (instantRate - rate));
} else {
rate = instantRate;
initialized = true;
}
}
Thanks,
Marian
It is thread safe because this line from tickIfNecessary() returns true only once per newIntervalStartTick
if (lastTick.compareAndSet(oldTick, newIntervalStartTick))
What happens if two threads enter tickIfNecessary() at almost the same time?
Both threads read the same value from oldTick, decide that at least TICK_INTERVAL nanoseconds have passed and calculate a newIntervalStartTick.
Now both threads try to do lastTick.compareAndSet(oldTick, newIntervalStartTick). As the name compareAndSet implies, this method compares to current value of lastTick to oldTick and only if the value is equal to oldTick it gets atomically replaced with newIntervalStartTick and returns true.
Since this is an atomic instruction (at the hardware level!), only one thread can succeed. When the other thread executes this method it will already see newIntervalStartTick as the current value of lastTick. Since this value no longer matches oldTick the update fails and the method returns false and therefore this thread does not call m1Rate.tick() to m15Rate.tick().
The EWMA.update(n) method uses a java.util.concurrent.atomic.LongAdder to accumulate the event counts that gives similar thread safety guarantees.
As far as I can see you are right. If tickIfNecessary() is called such that age > TICK_INTERVAL while another call is still running, it is possible that m1Rate.tick() and the other tick() methods are called at the same time from multiple threads. So it boils down to wether tick() and its called routines/operations are safe.
Let's dissect tick():
public void tick() {
final long count = uncounted.sumThenReset();
final double instantRate = count / interval;
if (initialized) {
rate += (alpha * (instantRate - rate));
} else {
rate = instantRate;
initialized = true;
}
}
alpha and interval are set only on instance initialization and marked final those thread-safe since read-only. count and instantRate are local and those not visible to other threads anyway. rate and initialized are marked volatile and those writes should always be visible for following reads.
If I'm not wrong, pretty much from the first read of initialized to the last write on either initialized or rate this is open for races but some are without effect like when 2 threads race for the switch of initialized to true.
It seems the majority of effective races can happen in rate += (alpha * (instantRate - rate)); especially dropped or mixed calculations like:
Assumed: initialized is true
Thread1: calculates count, instantRate, checks initialized, does the first read of rate which we call previous_rate and for whatever reason stalls
Thread2: calculates count, instantRate, checks initialized, and calculates rate += (alpha * (instantRate - rate));
Thread1: continues its operation and calculates rate += (alpha * (instantRate - previous_rate));
A drop would occur if the reads and writes somehow get ordered such that rate is read on all threads and then written on all threads, effectively dropping one or more calculations.
But the probability for such races, meaning that both age > TICK_INTERVAL matches such that 2 Threads run into the same tick() method and especially the rate += (alpha * (instantRate - rate)) may be extremely low and depending on the values not noticeable.
The mark() method seems to be thread-safe as long as the LongAdderProxy uses a thread-safe Data-structure for update/add and for the tick() method in sumThenReset.
I think the only ones who can answer the Questions left open - wether the races are without noticeable effect or otherwise mitigated - are the project authors or people who have in depth knowledge of these parts of the project and the values calculated.
This simple program has a shared array and 2 threads:
first thread - shows sum of values in the array.
second thread - subtracts 200 from one cell of the array and adds 200 to another cell.
I would expect to see the results: 1500 (sum of the array), 1300 (if the display occurs between the subtraction and the addition).
But for some reason, sometimes 1100 and 1700 appear, which I can't explain...
public class MainClass {
public static void main(String[] args) {
Bank bank = new Bank();
bank.CurrentSum.start();
bank.TransferMoney.start();
}
}
class Bank {
private int[] Accounts = { 100, 200, 300, 400, 500 };
private Random rnd = new Random();
Thread CurrentSum = new Thread("Show sum") {
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println(Accounts[0] + Accounts[1] + Accounts[2]
+ Accounts[3] + Accounts[4]);
}
}
};
Thread TransferMoney = new Thread("Tranfer"){
public void run(){
for(int i=0; i<50000; i++)
{
Accounts[rnd.nextInt(5)]-=200;
Accounts[rnd.nextInt(5)]+=200;
}
}
};
}
You are not updating the values in an atomic or thread safe manner. This means sometimes you see two more -200 than +200 and sometimes you see two more +200 than -200. As you iterate over the values it is possible to see a +200 value but the -200 value is an earlier value and you miss it, but you see another +200 update again missing the -200 change.
It should be possible to see up to 5 x +200 or 5 x -200 in rare cases.
It's happening because the addition of the five values is not atomic, and may be interrupted by the decrement and increment happening in the other thread.
Here's a possible case.
The display thread adds Accounts[0]+Accounts[1]+Accounts[2].
The updating thread decrements Accounts[0] and increments Accounts[3].
The updating thread decrements Accounts[1] and increments Accounts[4].
The display thread continues with its addition, adding Accounts[3] and Accounts[4] to the sum that it had already partially evaluated.
In this case, the sum will be 1900, because you've included two values after they've been incremented.
You should be able to work out cases like this, to give you sums of anything between 700 and 2300.
Perhaps on purpose, you are not doing the addition operation atomically.
That means that this line:
System.out.println(Accounts[0] + Accounts[1] + Accounts[2]
+ Accounts[3] + Accounts[4]);
Will run in multiple steps, any of which can occur during any iteration of the second thread.
1. Get value of Accounts[0] = a
2. Get value of Accounts[1] = b
...So on
The addition then happens after all the values are pulled from the array.
You can imagine that 200 is subtracted from Accounts[0], which is dereferenced by the JRE, then in another loop of the second thread, 200 is removed from Accounts[1], which is subsequently dereferenced by the JRE. This can result in the the output you see.
The Accounts variable is being accessed from more than one thread, one of which modifies its value. In order for the other thread to reliably read the modified values at all it is necessary to use a "memory barrier". Java has a number of ways of providing a memory barrier: synchronized, volatile or one of the Atomic types are the most common.
The Bank class also has some logic which requires the modifications to be made in multiple steps before the Accounts variable is back in a consistent state. The synchronized keyword can also be used to prevent another block of code that is synchronised on the same object from running until the first synchronized block has completed.
This implementation of the Bank class locks all access to the Accounts variable using the mutex lock object of the Bank object that owns the Accounts variable. This ensures that each synchronised block is run in its entirety before the other thread can run its own synchronised block. It also ensures that changes to the Accounts variable are visible to the other thread:
class Bank {
private int[] Accounts = { 100, 200, 300, 400, 500 };
private Random rnd = new Random();
Thread CurrentSum = new Thread("Show sum") {
public void run() {
for (int i = 0; i < 500; i++) {
printAccountsTotal();
}
}
};
Thread TransferMoney = new Thread("Tranfer"){
public void run(){
for(int i=0; i<50000; i++)
{
updateAccounts();
}
}
};
synchronized void printAccountsTotal() {
System.out.println(Accounts[0] + Accounts[1] + Accounts[2]
+ Accounts[3] + Accounts[4]);
}
synchronized void updateAccounts() {
Accounts[rnd.nextInt(5)]-=200;
Accounts[rnd.nextInt(5)]+=200;
}
}
public class counting
{
private static int counter = 0;
public void boolean counterCheck(){
counter++;
if(counter==10)
counter=0;
}
}
Method counterCheck can be accessed by multiple threads in my application. I know that static variables are not thread safe. I would appreciate if someone can help me with example or give me reason why I have to synchronize method or block. What will happen if I don't synchronize?
It's clearly not thread-safe. Consider two threads that run in perfect parallel. If the counter is 9, they'll each increment the counter, resulting in the counter being 11. Neither of them will then see that counter equal to 10, so the counter will keep incrementing from then on rather than wrapping as intended.
This is not thread safe, AND this pattern of updating a count from multiple threads is probably the #1 way to achieve negative scaling (it runs slower when you add more threads) of a multi-threaded application.
If you add the necessary locking to make this thread safe then every thread will come to a complete halt while counting. Even if you use atomic operations to update the counter, you will end up bouncing the CPU cache line between every thread that updates the counter.
Now, this is not a problem if each thread operation takes a considerable amount of time before updating the counter. But if each operation is quick, the counter updates will serialize the operations, causing everything to slow down on all the threads.
Biggest danger? Two increments to counter before the counter == 10 check, making the reset to 0 never happen.
It's NOT thread-safe, for multiple reasons. The most obvious one is that you could have two threads going from 9 to 11, as mentioned by other answers.
But since counter++ is not an atomic operation, you could also have two threads reading the same value and incrementing to the same value afterwards. (meaning that two calls in fact increment only by 1).
Or you could have one thread make several modifications, and the other always seeing 0 because due to the Java memory model the other thread might see a value cached in a register.
Good rule of thumb: each time some shared state is accessed by several threads, and one of them is susceptible to modify this shared state, all the accesses, even read-only accesses must be synchronized using the same lock.
Imagine counter is 9.
Thread 1 does this:
counter++; // counter = 10
Thread 2 does this:
counter++; // counter = 11
if(counter==10) // oops
Now, you might think you can fix this with:
if(counter >= 10) counter -= 10;
But now, what happens if both threads check the condition and find that it's true, then both threads decrement counter by 10 (now your counter is negative).
Or at an even lower level, counter++ is actually three operations:
Get counter
Add one to counter
Store counter
So:
Thread 1 gets counter
Thread 2 gets counter
Both threads add one to their counter
Both threads store their counter
In this situation, you wanted counter to be incremented twice, but it only gets incremented once. You could imagine it as if this code was being executed:
c1 = counter;
c2 = counter;
c1 = c1 + 1;
c2 = c2 + 1;
counter = c1; // Note that this has no effect since the next statement overrides it
counter = c2;
So, you could wrap it in a synchronized block, but using an AtomicInteger would be better if you only have a few threads:
public class counting {
private static AtomicInteger counter = new AtomicInteger(0);
public static void counterCheck() {
int value = counter.incrementAndGet();
// Note: This could loop for a very long time if there's a lot of threads
while(value >= 10 && !counter.compareAndSet(value, value - 10)) {
value = counter.get();
}
}
}
first of counter++ by itself is NOT threadsafe
hardware limitations make it equivalent to
int tmp = counter;
tmp=tmp+1;
counter=tmp;
and what happens when 2 threads are there at the same time? one update is lost that's what
you can make this thread safe with a atomicInteger and a CAS loop
private static AtomicInteger counter = new AtomicInteger(0);
public static boolean counterCheck(){
do{
int old = counter.get();
int tmp = old+1;
if(tmp==10)
tmp=0;
}
}while(!counter.compareAndSet(old,tmp));
}
How can I read an array in java in a certain time? Lets say in 1000 milliseconds.
for example:
float e[]=new float [512];
float step = 1000.0 / e.length; // I guess we need something like that?
for(int i=0; i<e.length; i++){
}
You'd need a Timer. Take a look at its methods... There's a number of them, but they can be divided into two categories: those that schedule at a fixed delay (the schedule(... methods) and those that schedule at a fixed rate (the scheduleAtFixedRate(... methods).
A fixed delay is what you want if you require "smoothness". That means, the time in between executions of the task is mostly constant. This would be the sort of thing you'd require for an animation in a game, where it's okay if one execution might lag behind a bit as long as the average delay is around your target time.
A fixed rate is what you want if you require the task's executions to amount to a total time. In other words, the average time over all executions must be constant. If some executions are delayed, multiple ones can then be run afterwards to "catch up". This is different from fixed delay where a task won't be run sooner just because one might have "missed" its cue.
I'd reckon fixed rate is what you're after. So you'd need to create a new Timer first. Then you'd need to call method scheduleAtFixedRate(TimerTask task, long delay, long period). That second argument can be 0 if you wish the timer to start immediately. The third argument should be the time in between task runs. In your case, if you want the total time to be 1000 milliseconds, it'd be 1000/array size. Not array size/1000 as you did.
That leaves us with the first argument: a TimerTask. Notice that this is an abstract class, which requires only the run() method to be implemented. So you'll need to make a subclass and implement that method. Since you're operating over an array, you'll need to supply that array to your implementation, via a constructor. You could then keep an index of which element was last processed and increment that each time run() is called. Basically, you're replacing the for loop by a run() method with a counter. Obviously, you should no longer do anything if the counter has reached the last element. In that case, you can set some (boolean) flag in your TimerTask implementation that indicates the last element was processed.
After creating your TimerTask and scheduling it on a Timer, you'll need to wait for the TimerTask's flag to be set, indicating it has done its work. Then you can call cancel() on the Timer to stop it. Otherwise it's gonna keep calling useless run() methods on the task.
Do keep the following in mind: if the work done in the run() method typically takes longer than the interval between two executions, which in your case would be around 2 milliseconds, this isn't gonna work very well. It only makes sense to do this if the for loop would normally take less than 1 second to complete. Preferably much less.
EDIT: oh, also won't work well if the array size gets too close to the time limit. If you want 1000 milliseconds and you have 2000 array elements, you'll end up passing in 0 for the period argument due to rounding. In that case you might as well run the for loop.
EDIT 2: ah why not...
import java.util.Random;
import java.util.Timer;
public class LoopTest {
private final static long desiredTime = 1000;
public static void main(String[] args) {
final float[] input = new float[512];
final Random rand = new Random();
for(int i = 0; i < input.length; ++i) {
input[i] = rand.nextFloat();
}
final Timer timer = new Timer();
final LoopTask task = new LoopTask(input);
double interval = ((double)desiredTime/((double)input.length));
long period = (long)Math.ceil(interval);
final long t1 = System.currentTimeMillis();
timer.scheduleAtFixedRate(task, 0, period);
while(!task.isDone()) {
try {
Thread.sleep(50);
} catch(final InterruptedException i) {
//Meh
}
}
final long t2 = System.currentTimeMillis();
timer.cancel();
System.out.println("Ended up taking " + (t2 - t1) + " ms");
}
}
import java.util.TimerTask;
public class LoopTask extends TimerTask {
private final float[] input;
private int index = 0;
private boolean done = false;
public LoopTask(final float[] input) {
this.input = input;
}
#Override
public void run() {
if(index == input.length) {
done = true;
} else {
//TODO: actual processing goes here
System.out.println("Element " + index + ": " + input[index]);
++index;
}
}
public boolean isDone() {
return done;
}
}
Change your step to be time per number (or total time divided by number of steps)
float step = 1000.0 / e.length;
Inside your for() loop:
try{
Thread.sleep(step);
}catch(InterruptedException e){
e.printStackTrace();
}