I am trying to count how many instances of a class generated during the run time of a process under multi-threading environment. The way how I do it is to increase a static counter in the constructor by looking at this post:
How to Count Number of Instances of a Class
So in multi-threading environment, here is how i define the class:
class Television {
private static volatile int counter = 0;
public Television(){
counter ++;
}
}
However, I am not sure whether there is a potential bug with the code above since I think constructor in java does not imply synchronization and counter++ is not atomic so if two threads are creating instances simultaneously, is the code a bug somehow? but I am not quite sure yet.
There is a bug in this code (specifically, a race condition), because the read of counter and write to counter aren't atomically executed.
In other words, two threads can read the same value of counter, increment that value, and then write the same value back to the variable.
Thread 1 Thread 2
======== ========
Read 0
Read 0
Increment
Increment
Write 1
Write 1
So the value would be 1, not 2, afterwards.
Use AtomicInteger and AtomicInteger.incrementAndGet() instead.
As counter++ is NOT atomic, you can replace it with JDK's AtomicInteger which is threadsafe.
You can AtomicInteger's use getAndIncrement() method as shown below:
class Television {
private static final AtomicInteger counter = new AtomicInteger();
public Television(){
counter.getAndIncrement();
}
}
An AtomicInteger is used in applications such as atomically
incremented counters, and cannot be used as a replacement for an
Integer.
You can look here
There are two ways here to bypass the underlying "++ on int" not being an atomic operation:
A) as others suggested, use AtomicInteger
B) introduce a common LOCK that all ctors can be using to sync on; like:
private final static Object LOCK = new Object();
public Television() {
synchronized (LOCK) {
counter++;
}
Related
I have a situation where one thread updates int and another one at some point reads it. So single-reader single-writer.
So far I was using volatile int for that purpose, but since this forces full sync on memory barriers I was thinking about something else.
One approach would be AtomicInteger.incrementAndGet()
but I think this has exactly the same effect and will actually be slower
Another approach would be to use AtomicInteger.lazySet with extra non-volatile counter for writer.
So basically we would have
private int counter;
public AtomicInteger visibleCounter = new AtomicInteger();
private void write() {
counter++
visibleCounter.lazySet(counter)
}
// called by reader
public int isCountEqual(int val) {
return val == visibleCounter.get()
}
as a naive "lazyIncrement".
Would it be actually more performant than simple increment of volatile int by writer?
Thanks
If lazy increment is one of your options I'll suggest LongAdder. link
LongAdder is good for multiple threads updates.
... under high contention, expected throughput of this class is significantly higher (than AtomicLong)
I am trying to see how volatile works here. If I declare cc as volatile, I get the output below. I know thread execution output varies from time to time, but I read somewhere that volatile is the same as synchronized, so why do I get this output? And if I use two instances of Thread1 does that matter?
2Thread-0
2Thread-1
4Thread-1
3Thread-0
5Thread-1
6Thread-0
7Thread-1
8Thread-0
9Thread-1
10Thread-0
11Thread-1
12Thread-0
public class Volexample {
int cc=0;
public static void main(String[] args) {
Volexample ve=new Volexample();
CountClass count =ve.new CountClass();
Thread1 t1=ve.new Thread1(count);
Thread2 t2=ve.new Thread2(count);
t1.start();
t2.start();
}
class Thread1 extends Thread{
CountClass count =new CountClass();
Thread1(CountClass count ){
this.count=count;
}
#Override
public void run() {
/*for(int i=0;i<=5;i++)
count.countUp();*/
for(int i=0;i<=5;i++){
cc++;
System.out.println(cc + Thread.currentThread().getName());
}
}
}
class Thread2 extends Thread {
CountClass count =new CountClass();
Thread2(CountClass count ){
this.count=count;
}
#Override
public void run(){
/*for(int i=0;i<=5;i++)
count.countUp();*/
for(int i=0;i<=5;i++){
cc++;
System.out.println(cc + Thread.currentThread().getName());
}
}
}
class CountClass{
volatile int count=0;
void countUp(){
count++;
System.out.println(count + Thread.currentThread().getName());
}
}
}
In Java, the semantics of the volatile keyword are very well defined. They ensure that other threads will see the latest changes to a variable. But they do not make read-modify-write operations atomic.
So, if i is volatile and you do i++, you are guaranteed to read the latest value of i and you are guaranteed that other threads will see your write to i immediately, but you are not guaranteed that two threads won't interleave their read/modify/write operations so that the two increments have the effect of a single increment.
Suppose i is a volatile integer whose value was initialized to zero, no writes have occurred other than that yet, and two threads do i++;, the following can happen:
The first thread reads a zero, the latest value of i.
The second threads reads a zero, also the latest value of i.
The first thread increments the zero it read, getting one.
The second thread increments the zero it read, also getting one.
The first thread writes the one it computed to i.
The second thread writes the one it computed to i.
The latest value written to i is one, so any thread that accesses i now will see one.
Notice that an increment was lost, even though every thread always read the latest value written by any other thread. The volatile keyword gives visibility, not atomicity.
You can use synchronized to form complex atomic operations. If you just need simple ones, you can use the various Atomic* classes that Java provides.
A use-case for using volatile would be reading/writing from memory that is mapped to device registers, for example on a micro-controller where something other than the CPU would be reading/writing values to that "memory" address and so the compiler should not optimise that variable away .
The Java volatile keyword is used to mark a Java variable as "being stored in main memory". That means, that every read of a volatile variable will be read from the computer's main memory, and not from the cache and that every write to a volatile variable will be written to main memory, and not just to the cache.
It guarantees that you are accessing the newest value of this variable.
P. S. Use larger loops to notice bugs. For example try to iterate 10e9 times.
In my program I have one thread incrementing a supply variable by 2, then another thread takes a random number of supply from a supply class. The supply class can only store up to 5 values and because the sleep and supply requests are random, the supply count can increment over it's max limit.
What I'm trying to make sure is that it doesn't go over that limit.
Is there a better way to do this?
(pseudocode)
increment supply by 2
if supply is more than max then assign supply to max
Here is the code:
private int MAX = 5;
private int supply = 0;
public void run()
{
while(true) {
supply = supply + 2;
if(supply > MAX)
supply = MAX;
}
}
You could use a public synchronized incSupply() method which is used to increment the supply variable:
public synchronized void incSupply()
{
// Code borrowed from Jean-Bernard Pellerin.
int temp = supply + 2;
if (temp > MAX)
temp = MAX;
supply = temp;
}
Note that you need to use synchronized also for other methods that read/write from/to the 'supply' variable.
int temp = supply + 2;
if (temp > MAX)
temp = MAX;
supply = temp;
This is still not thread-safe though. You should look into locks and synchronization.
If you have more than one thread you should declare your common resource,(meaning other threads execute commands on that variable) in your case i guess would be the supply, as synchronized. and use fine-grained synchronization
synchronized(this) {
supply = supply+2
}
I dont entirely understand this part of your question: and the other thread takes a random number of supply from the supply class. Does this mean the consuming thread can take a random number of values from the supply class, or a value which is a random number?
In any case, you have a resource which requires mutually exclusive access, so you need to ensure that only one thread can modify it. In java, this is easily done by requesting a intrinsic lock on the instance being modified, only one thread can hold this lock at any given time. Now, when a thread encounters a synchronized block (as per Stelsavva's example) it automatically will try and obtain the intrinsic lock on whichever instance this represents, and hold it until the end of the block. If any other thread encounters the block, while another thread is holding the lock, it will wait until the lock is released by the other thread.
Hence, the execution is of the block is synchronised and you wont have problems with interleaving.
Use a Semaphore with five permits. Somewhat counterintuitively, I think the permit would represent the permission to store a supply, so the first thread would need to acquire permits to store the supplies. When the second thread takes supplies, it releases this many permits.
The simplest solution is to use AtomicInteger without going throughout the trouble of synchronizing the increment:
private int MAX = 5;
private AtomicInteger supply = new AtomicInteger(0);
public void run()
{
while(true) {
if(supply.addAndGet(2) > MAX)
supply.set(MAX);
}
}
In the below code listings, are Statement 1 and Statement 2 thread safe or not? They are using the VolatileIntWrapper.
If they not thread safe, which statements need to be wrapped in synchronized block?
public class Demo {
public static void main(String[] args) {
VolatileIntWrapper volatileIntWrapper = new VolatileIntWrapper() ;
for(int i = 1 ; i <= 5 ; ++i){
new ModifyWrapperIntValue(volatileIntWrapper).start() ;
}
}
}
class VolatileIntWrapper{
public volatile int value = 0 ;
}
class ModifyWrapperIntValue extends Thread{
private VolatileIntWrapper wrapper ;
private int counter = 0 ;
public ModifyWrapperIntValue(VolatileIntWrapper viw) {
this.wrapper = viw ;
}
#Override
public void run() {
//randomly increments or decrements VolatileIntWrapper primitive int value
//we can use below statement also, if value in VolatileIntWrapper is private
// wrapper.getValue() instead of wrapper.value
//but, as per my understanding, it will add more complexity to logic(might be requires additional synchronized statements),
//so, for simplicity, we declared it public
//Statement 1
while(wrapper.value > -1500 && wrapper.value < 1500){
++counter ;
int randomValue = (int) (Math.random() * 2) ;
//Statement 2
wrapper.value += (randomValue == 0) ? 1 : -1 ;
}
System.out.println("Executed " + counter + " times...");
}
}
The volatile keyword provides a memory barrier for both reading and writing a field. That means that multiple threads can access the field and be guaranteed to read the most current value and their writes are guaranteed to be seen by other threads.
What volatile does not do is provide any guarantees around the order of operations -- especially when you have multiple read and write statements. In your code you are accessing the volatile int a couple of places in your loop:
while(wrapper.value > -1500 && wrapper.value < 1500){
...
wrapper.value += (randomValue == 0) ? 1 : -1 ;
}
There are no guarantees as to the order of operations here. Immediately after thread A tests the value > -1500, another thread might change it before thread A can test value < 1500. Or thread A might do both tests, then thread B might do both tests, then thread A would assign the value, and then thread B would assign the value. That is the nature of multithreading race conditions.
The while loop is the section of code that I suspect would be considered have a bug unless you synchronize around it. You should do something like the following. Once you are synchronizing that section, the synchronized keyword provides the memory barrier itself and so the volatile keyword is unnecessary.
synchronized (wrapper) {
while (...) {
...
}
}
It is safe to use a volatile field once and only once. (A read and a write counts as twice)
You are using the field a total of four times so you have three places for a race condition.
The problem with this example is it is faster and simpler to be performed single threaded, so anything you do with it in a multi-threaded way will appear unnatural and inefficient.
The question needs the following interpretation:
The thread you are using is safe and you are reading your primitive value as it is intended.
there is a specific term to use synchronize blocks on the primitive field, but you need to do the following:
Use getter and setters of your field.
Put synchronize in the both accessors and voila.
Java In Concurrencty says the following criteria need to be met touse volatile variables:
1. Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value;
2. The variable does not participate in invariants with other state variables; and
3. Locking is not required for any other reason while the variable is being accessed.
Consider code sniper below:
package sync;
public class LockQuestion {
private String mutable;
public synchronized void setMutable(String mutable) {
this.mutable = mutable;
}
public String getMutable() {
return mutable;
}
}
At time Time1 thread Thread1 will update ‘mutable’ variable. Synchronization is needed in setter in order to flush memory from local cache to main memory.
At time Time2 ( Time2 > Time1, no thread contention) thread Thread2 will read value of mutable.
Question is – do I need to put synchronized before getter? Looks like this won’t cause any issues - memory should be up to date and Thread2’s local cache memory should be invalidated&updated by Thread1, but I’m not sure.
Rather than wonder, why not just use the atomic references in java.util.concurrent?
(and for what it's worth, my reading of happens-before does not guarantee that Thread2 will see changes to mutable unless it also uses synchronized ... but I always get a headache from that part of the JLS, so use the atomic references)
It will be fine if you make mutable volatile, details in the "cheap read-write lock"
Are you absolutely sure that the getter will be called only after the setter is called? If so, you don't need the getter to be synchronized, since concurrent reads do not need to synchronized.
If there is a chance that get and set can be called concurrently then you definitely need to synchronize the two.
If you worry so much about the performance in the reading thread, then what you do is read the value once using proper synchronization or volatile or atomic references. Then you assign the value to a plain old variable.
The assign to the plain variable is guaranteed to happen after the atomic read (because how else could it get the value?) and if the value will never be written to by another thread again you are all set.
I think you should start with something which is correct and optimise later when you know you have an issue. I would just use AtomicReference unless a few nano-seconds is too long. ;)
public static void main(String... args) {
AtomicReference<String> ars = new AtomicReference<String>();
ars.set("hello");
long start = System.nanoTime();
int runs = 1000* 1000 * 1000;
int length = test(ars, runs);
long time = System.nanoTime() - start;
System.out.printf("get() costs " + 1000*time / runs + " ps.");
}
private static int test(AtomicReference<String> ars, int runs) {
int len = 0;
for (int i = 0; i < runs; i++)
len = ars.get().length();
return len;
}
Prints
get() costs 1219 ps.
ps is a pico-second, with is 1 millionth of a micro-second.
This probably will never result in incorrect behavior, but unless you also guarantee the order that the threads startup in, you cannot necessarily guarantee that the compiler didn't reorder the read in Thread2 before the write in Thread1. More specifically, the entire Java runtime only has to guarantee that threads execute as if they were run in serial. So, as long as the thread has the same output running serially under optimizations, the entire language stack (compiler, hardware, language runtime) can do
pretty much whatever it wants. Including allowing Thread2 to cache the the result of LockQuestion.getMutable().
In practice, I would be very surprised if that ever happened. If you want to guarantee that this doesn't happen, have LockQuestion.mutable be declared as final and get initialized in the constructor. Or use the following idiom:
private static class LazySomethingHolder {
public static Something something = new Something();
}
public static Something getInstance() {
return LazySomethingHolder.something;
}