Consider the following two threads of a process, to be run concurrently in a sha
ID: 3805717 • Letter: C
Question
Consider the following two threads of a process, to be run concurrently in a shared memory (all variables are shared between the two threads): Assume the following: 1. a single-core system 2. load and store are atomic (i.e. they start and finish without interruption) 3. x is initialized to 0 before either thread starts, and 4. x must be loaded into a register before being incremented (and stored back to memory afterwards). The following questions consider the final value of x after both threads have completed. 1b Suppose we replace 'x = x + 2' in Thread B with an atomic double increment operation atomiclncr 2(x) that cannot be preempted while being executed. What are ALL possible final values of x? Explain.Explanation / Answer
1a.
package chegg;
public class TwoThreadProcess {
public static void main(String[] args) {
final AtomicVariable atomicVariable = new AtomicVariable();
Thread t1 = new Thread(new Thread1(atomicVariable));
t1.setName("Thread-1");
Thread t2 = new Thread(new Thread2(atomicVariable));
t2.setName("Thread-2");
t1.start();
t2.start();
}
}
class Thread1 implements Runnable {
private AtomicVariable atomicVariable;
public Thread1(AtomicVariable atomicVariable) {
super();
this.atomicVariable = atomicVariable;
}
@Override
public void run() {
synchronized (this.atomicVariable) {
for (int i = 0; i < 5; i++) {
this.atomicVariable.x = this.atomicVariable.x + 1;
System.out.println(Thread.currentThread().getName()
+ " Incremented value " + this.atomicVariable.x);
}
}
}
}
class Thread2 implements Runnable {
private AtomicVariable atomicVariable;
public Thread2(AtomicVariable atomicVariable) {
super();
this.atomicVariable = atomicVariable;
}
@Override
public void run() {
synchronized (this.atomicVariable) {
for (int i = 0; i < 5; i++) {
this.atomicVariable.x = this.atomicVariable.x + 2;
System.out.println(Thread.currentThread().getName()
+ " Incremented value " + this.atomicVariable.x);
}
}
}
}
class AtomicVariable {
public volatile int x = 0;
}
description :
1. x has been initialized to 0 before either thread starts.
2. x taken as volatile which given a guarantee of visibility ( load x in ragister and increment value of it and stored back to main memory immdiately)
3. Synchronization block will be applied so that one thread can perform operation at a time.
1a. Output
---------------
Thread-1 Incremented value 1
Thread-1 Incremented value 2
Thread-1 Incremented value 3
Thread-1 Incremented value 4
Thread-1 Incremented value 5
Thread-2 Incremented value 7
Thread-2 Incremented value 9
Thread-2 Incremented value 11
Thread-2 Incremented value 13
Thread-2 Incremented value 15
1b. since increment operation on long or double is not thread-safe like integer etc beacuse double takes 8 bytes or 64 bit memory to store the whole value and 32 bit operating system breaks that 64 bit value or read the same in two parts so it might be possible that one thread is performing operation on one part of vaiable value and the second thread will be performing operation on second part of that variable due to values avaible in cache so it's better to use ready made classes like AtomicLong or AtomicIneger instead of same.
using AtomicLong or AtomicIneger , no synchonization will be required and we can achieve the same result as given in program 1a above.
If we choose atomic double variable and increment operation performs on same than no need of synchronization will required beacuse increment operation already thread safe and output would be the same in that case.
Please find below code and their output for atomic double