Using volatile variable from properly object reference - java

I want to make an object in a new thread, that will create another thread. In that last created threads I need a reference for variable from exact object that created this thread. So far I have this code:
Main
public static void main(String[] args) {
for(int i = 0; i < 2; i++){
ClassThread ct = new ClassThread();
Thread t = new Thread(ct);
t.start();
}
}
ClassThread
public static volatile int liczba = 1;
private static int id = 0;
#Override
public void run() {
for(int i = 0; i < 2; i++){
Class1 cla = new Class1(liczba, id);
Thread t = new Thread(cla);
t.start();
id++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Class1
private volatile int var;
private int id;
public Class1(int _var, int _id) {
var = _var;
id = _id;
}
#Override
public void run() {
while(true){
System.out.println("Thread: " + id + " : " + var);
var++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

If you need to get an int reference from one thread to another, you either have to specify your own MutableInteger class, or use AtomicInteger. The atomic integer has the positive side-effects in that operations can be made atomic. For a more exhaustive answer, see This answer.
If the question is regarding non-primitive types, you can simply pass the needed reference to the constructor as you are already attempting to do. Any changes to the internal state of that object will be reflected to all holders of a reference. Some objects are immutable (String being the perhaps most well-known, but be aware that Integer, Long, etc. works the same way.), and can therefore not be used in this way.
Do note that if you pass a reference, any assignments done to your internal reference var = "hello"; will not affect anything outside your class. You will simply exchange your private reference for another one, leaving all other references to the old object as they are. This has to do with the fact that Java is always pass-by-value.

Related

What will happen when we create lock (Synchronized block) object inside a method?

public class SampleExecutorService {
private static int count = 0;
private void increment() {
Object lock = new Object();
synchronized (lock) {
count++;
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
SampleExecutorService obj = new SampleExecutorService();
Runnable task = obj::increment;
for (int i = 0; i < 1000; i++) {
executorService.submit(task);
}
executorService.shutdown();
try {
executorService.awaitTermination(2, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("count : " + count);
}
}
The expected result for the above program is 1000, but it not gives that result since I followed the synchronization mechanism.But it works fine if we create a lock object in class level instance variable. The right code snippet is below
public class SampleExecutorService {
private static int count = 0;
Object lock = new Object();
private void increment() {
//Object lock = new Object();
synchronized (lock) {
count++;
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
SampleExecutorService obj = new SampleExecutorService();
Runnable task = obj::increment;
for (int i = 0; i < 1000; i++) {
executorService.submit(task);
}
executorService.shutdown();
try {
executorService.awaitTermination(2, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("count : " + count);
}
}
I want know, what will happen when we create lock object inside a method? what is the difference between lock object creation inside a method and as instance variable?
Local variables are stored on thread stack and are created for each thread separately. If the local variable is not a primitive, then the instance itself is stored on the heap, but the reference to object is stored on the thread stack. That's why local variables are thread-safe.
Since the global variables are stored on the heap and are shared/visible by multiple threads they need to be synchronized.
So in your first example you are creating new lock for each thread, so multiple threads are still able to access it.
Here's an excellent article on Java Memory Model

Is RMI automatically "thread safe"?

I'm learning how to use Java RMI in order to code distribuded applications.
I wrote a simple program just to test some things out, I just give integers to a server through a client, and the server accumulates them in a static variable. Here is the code:
The server:
public class Adder extends UnicastRemoteObject implements IAdder {
/**
*
*/
private static final long serialVersionUID = 8229278619948724254L;
private static Integer sum = 0;
static Logger logger = Logger.getLogger("global");
protected Adder() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
#Override
public void add(int i) throws RemoteException {
System.out.println("Got: " + i);
synchronized (sum) {
sum += i;
System.out.println("The new sum is: " + sum);
}
}
#Override
public int result() throws RemoteException {
System.out.println("The sum is: " + sum);
return sum;
}
public static void main(String[] args) {
System.setSecurityManager(new SecurityManager());
try {
logger.info("Building remote object");
Adder obj = new Adder();
logger.info("Binding");
Naming.rebind("SommaServer", obj);
logger.info("Ready");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client:
public class Client extends Thread {
static Logger logger = Logger.getLogger("global");
private IAdder obj;
private int array[] = new int[3];
public static void main(String[] args) {
try {
Client c1 = new Client(1);
Client c2 = new Client(2);
c1.start();
c2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void work(int i) throws RemoteException {
obj.add(i);
}
public void run() {
Random rn = new Random();
try {
work(array[0]);
work(array[1]);
work(array[2]);
} catch (Exception e) {
e.printStackTrace();
}
}
public Client(int i) throws Exception {
if (i == 1) {
array[0] = 1;
array[1] = 3;
array[2] = 4;
}
if (i == 2) {
array[0] = 7;
array[1] = 2;
array[2] = 5;
}
logger.info("Remote object lookup");
obj = (IAdder) Naming.lookup("rmi://localhost/SommaServer");
}
}
In the main of the client I create two client threads, and run them (there are no synchronicity checks I know, but I'm just trying things out). Each thread has an array of numbers to feed to the server.
The server receives them and then adds them all togheter.
So, since I'm dealing with threads, my first thought was that I needed to use a lock on the update of the sum, otherwise I would likely get errors because of the interleaving of the threads. Hence the synchronized block in the server.
But then, to see what would happen, I removed the block, and I was still getting the right result, all the time (the values is 22).
Just to be sure I made a "local" version of the client too, which updates a local variable:
public class Client extends Thread {
private static Integer sum = 0;
static Logger logger = Logger.getLogger("global");
private IAdder obj;
private int array[] = new int[3];
public static void main(String[] args) {
try {
Client c1 = new Client(1);
Client c2 = new Client(2);
c1.start();
c2.start();
c1.join();
c2.join();
System.out.println("Ricevuto: " + sum);
} catch (Exception e) {
e.printStackTrace();
}
}
public void work(int i) throws RemoteException {
//obj.add(i);
synchronized(sum) {
sum += i;
}
}
public void run() {
Random rn = new Random();
try {
work(array[0]);
work(array[1]);
work(array[2]);
} catch (Exception e) {
e.printStackTrace();
}
}
public Client(int i) throws Exception {
if (i == 1) {
array[0] = 1;
array[1] = 3;
array[2] = 4;
}
if (i == 2) {
array[0] = 7;
array[1] = 2;
array[2] = 5;
}
}
}
With synchronization I get the right result, without I get various numbers (8, 15, 14, 22...)
So, what is going on exactly? I doubt RMI can just be thread safe like that.
Extra question: When I bind an object in RMI, what exactly am I binding? The specific instance of the object I call Naming.rebind() on, or the class(and then when I look it up I just get a new instance?)?
Your synchronization is broken, so you can't deduce much by your experiment. Each time you do sum += i, you assign a new Integer to sum. So the threads synchronize on two different Integers.
Also, you're binding an instance of Sommatore, but you're showing the code of Adder.
But to answer your question, you're binding an instance, and RMI won't magically create copies of that instance. It won't synchronize all calls to this instance either. So you need to make sure the code is thread-safe. Just because a quick test produces a correct result despite the absence of proper synchronization doesn't mean that it will always be that way. You can cross a road with your eyes shut 10 times and never die. That doesn't mean it's safe.
Is RMI automatically "thread-safe"?
No.
Extra question: when I bind an object in RMI, what exactly am I binding? The specific instance of the object I call Naming.rebind() on, or the class(and then when I look it up I just get a new instance?)?
Actually neither. You are binding a stub, which is irretrievably associated with the remote object instance you supplied to the bind() method.

Java monitor returns wrong value from private variable

I'm implementing a barrier in java that when accesed by a thread it creates a new object, with a value from the parameter, stored in a private variable to later be returned. Then, when another thread calls the barrier it completes the former object with this other parameter. The first pair goes on well, the rest receive the same object the first pair created.
private Barrier aBarrier;
private boolean first = true;
public synchronized Barrier pairUp(int id){
try{
if(first){
first = false;
aBarrier = new Barrier(); aBarrier.setFirst(id);
wait();
}
else{
first = true;
aBarrier.setLast(id);
notify();
}
}
catch(InterruptedException e){System.out.printf("ERROR");}
return aBarrier;
}
And this would be what every process calling the method above looks like.
private int id = ID OF THE PROCESS, 14 RUN CONCURRENTLY SO FROM 0 TO 13 (this is set in the constructor method);
public void run() {
while(true){
myBarrier = pairUp(id);
myBarrier.goThrough();
//Do stuff that doesn't matter here
// ....
}
}
A Barrier object contains two integers and a method to do more stuff later.
If I reset the private variable aBarrier to null before or after the calls it always gives null back.
I feel like I'm missing some stupid thing here.
If a process calls the method pairUp() after the first pair it will get the first Barrier.
I use this to diferentiate which process came first in the pairUp method.
Thanks beforehand!
A Barrier object contains two integers and a method to do more stuff later. If I reset the private variable aBarrier to null before or after the calls it always gives null back. I feel like I'm missing some stupid thing here.
I think the problem is that you are returning aBarrier after the wait/notify calls but it might have been changed by subsequent threads. Storing it in a local variable so it won't be changed is key.
You might also have had multiple versions of the wrapping object so your synchronized statement is synchronizing on a different object?
Couple things to note in the code below:
The System.out.println(...) changes the synchronization. Need to be careful here.
I used the aBarrier being null or not to replace the first boolean.
Code:
public class Foo implements Runnable {
private static int NUM_THREADS = 14;
private static final AtomicInteger idCounter = new AtomicInteger();
private static final ExecutorService threadPool = Executors.newFixedThreadPool(NUM_THREADS);
private static Barrier aBarrier = null;
public static void main(String[] args) {
// only 1 Foo object
Foo foo = new Foo();
for (int i = 0; i < NUM_THREADS; i++) {
threadPool.execute(foo);
}
}
public synchronized Barrier pairUp(int id) {
Barrier barrier = aBarrier;
try {
if (barrier == null) {
barrier = new Barrier();
barrier.first = id;
aBarrier = barrier;
wait();
} else {
barrier.last = id;
aBarrier = null;
notify();
}
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
e.printStackTrace();
barrier = null;
}
// return local barrier because aBarrier might have changed
return barrier;
}
#Override
public void run() {
int id = idCounter.incrementAndGet();
while (true) {
Barrier myBarrier = pairUp(id);
// System.out.println is synchronized so it may move the bug
System.out.println(id + ": " + myBarrier.first + " and " + myBarrier.last);
}
}
private static class Barrier {
int first;
int last;
}
}

java: Passing a class reference to another thread

I'm trying to learn how to use multithreading in Java. I have a main and two classes which extend Thread, A and B. I want the main to start A, which makes multiple calls to B. Once A is finished, I want B to send something to main.
The main creates two threads, one A and one B, and then starts both threads. A does something, which will then pass on a result to B. The main then collects an answer from B and does something else. I don't know how to get the total from B back to the main.
I'm also not sure how to instantiate the two classes (threads) but then give A a reference of B since Java uses pass-by-value. Can someone give me some pointers.
public static void main(String[] args)
{
B b = new B();
A a = new A(100, b);
B.start();
A.start();
A.join(); // Waiting for A to die
// Here I want to get a total from B, but I'm not sure how to go about doing that
}
public class A extends Thread
{
private int start;
// Some reference to B
B b;
public A (int n, B b) {
int start = n;
this.b = b;
}
public void run() {
for (int i = 0; i < n; i++) {
b.add(i);
}
}
}
public class B extends Thread
{
private int total;
public B () {
total = 0;
}
public void add(int i) {
total += i;
}
}
I changed your example code into what I consider to be a more meaningful example.
Communication between threads is usually handled through shared data (or channels like pipes, sockets - but I wont go there...). And while it is perfectly alright to have this shared data contained within the thread classes I have seperated the shared data from the data/methods used to administer the threads.
I hope this helps you to understand the relationship between threads and data objects.
public class TestThreads {
public static void main(String[] args)
{
DataShare ds = new DataShare();
B b = new B(ds);
A a = new A(100, ds);
b.start();
a.start();
try {
a.join(); // Waiting for A to die
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println ("Accumulated total from B = " + b.getTotal());
b.endThread();
}
}
public class DataShare {
private int value;
public DataShare () {
value = -1;
}
public synchronized boolean setValue(int val) {
boolean valueSet = false;
if (value == -1) {
value = val;
valueSet = true;
}
return valueSet;
}
public synchronized int getValue() {
int val = value;
value = -1;
return val;
}
}
public class A extends Thread {
private int max;
private DataShare dataShare;
public A (int n, DataShare ds) {
max = n;
dataShare = ds;
}
public void run() {
int i = 0;
while (i < max) {
if (dataShare.setValue(i)) {
i++;
}
}
}
}
public class B extends Thread {
private int total;
private DataShare dataShare;
private boolean running = false;
public B (DataShare ds) {
dataShare = ds;
total = 0;
}
public void run() {
running = true;
while (running) {
int nextValue = dataShare.getValue();
if (nextValue != -1) {
total += nextValue;
}
}
}
public int getTotal() {
return total;
}
public synchronized void endThread() {
running = false;
}
}
I am aware that this naive example is far from optimal since both threads are wasting precious cycles while waiting for the value to be set/read. I just wanted to keep the example as simple as possible while still addressing the point I'm trying to make.
A decent way to do it. You just pass an instance of class A:
public class Foo {
public void doFoo() {..} // that's the method you want to use
}
public class Bar {
private Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public void doSomething() {
foo.doFoo(); // here you are using it.
}
}
And then you can have:
Foo foo = new Foo();
Bar bar = new Bar(foo);
bar.doSomething();
First of all, B should not be a thread. If all it does is respond to messages from A, then it can just be an object like any other.
Second, while everyone says java uses pass by value, the confusing part is that object references are passed by value, so objects are effectively passed by reference. Thus, you can pass B to A, and get the total from your copy of B.
If we look at your code:
B b = new B();
A a = new A(100, b);
B.start();
A.start();
A.join(); // Waiting for A to die
// Here I want to get a total from B, but I'm not sure how to go about doing that
You are passing a pointer of b to A. That means that if class A only accesses class B directly (it does not replace it with a new instance of B) that the object should contain anything that class A did to it. In other words, both your main code and class A work on the same object of B. So you should be able to get the total of b simply by asking the object you have instantiated in main.
So if you call
b.total();
at the end of main, it should return your value (of course you must ensure that thread A will not make changes to it after retrieving the value).
I assume that you are trying to achieve communication between the two threads you create in the main method. This is, however, not happening. I made a few changes to your code and included it below to show what I think you wanted to do.
First, a few corrections of your examples:
You cannot use class names (A and B) when referencing thread objects as you do in the main method. Use the object names instead (a and b).
In class A constructor you are creating a new local variable start instead of referencing the member variable. Hence: int start = n should be start = n
I'm guessing you want to loop the number of times set in constructor. Hence for (int i = 0; i < n; i++) { should be for (int i = 0; i < start; i++) {
Pass by reference/value is not really relevant here. Object references are passed by value as anything else is. It is, however, the contents of the reference variable (the object address) which is interesting and that will not change. In other words, when passing an object reference to a method, the method WILL address that specific object, and any change made to the contents of the objects will be visible outside the method as well.
Here are your examples with a few corrections as I think you intended them.
public class TestThreads {
public static void main(String[] args)
{
B b = new B();
A a = new A(100, b);
b.start();
a.start();
try {
a.join(); // Waiting for A to die
} catch (InterruptedException e) {
e.printStackTrace();
}
// Getting a total from b is simple, if you provide the method for it
System.out.println ("Accumulated total from B = " + b.getTotal());
}
}
public class A extends Thread {
private int start;
// Some reference to B
B b;
public A (int n, B b) {
start = n;
this.b = b;
}
public void run() {
for (int i = 0; i < start; i++) {
b.add(i);
}
}
}
public class B extends Thread {
private int total;
public B () {
total = 0;
}
public void add(int i) {
total += i;
}
public int getTotal() {
return total;
}
}
Now, here is the problem with these examples:
An object is not a thread and vice versa. In the main thread (lets call that thread tM) You are creating an object of class B and forking a new thread (thread tB) starting in its run() method. However, since you did not override the run method, the threat ends immediately after creation.
Then you create an object of class A. Gives it the reference to object b (which has nothing to do with thread tB) and fork a new thread (thread tA). Here you did implement a run() method. The result is the following:
Thread tM did the initial work and is now waiting for thread tA to finish.
Thread tB was started and died immediately afterwards
Thread tA is doing all the work of incrementing the counter of object a, and making object b add the counter to its sum.
When tA finished after 100 increments tM wakes up and acquires the sum from object b (which again has nothing to do with thread tB).

Uses of volatile without synchronization

Knowing that
Reads and writes are atomic for all variables declared volatile
Question1: Can this be understood as if
private volatile int x = 0;
x++; operation is atomic?
And that
Marking variable volatile does not eliminate all need to synchronize
atomic actions, because memory consistency errors are still possible.
Question2: I wonder under what circumstances (if any) it is possible to see a variable marked volatile and not see any methods of blocks marked synchronized (that attempt to access/ modify the variable)?
In other words, should all variables that need to be protected from concurrent modification be marked volatile?
The volatile only gives you additional visibility guarantees, atomic writes/reads for longs/doubles (otherwise not guaranteed by the JLS, yes) and some memory order guarantees. No synchronization (it is possible though to build synchronization blocks starting with just volatile - Dekker's algorithm )
So no, it does not help you with x++ - that's still a read, inc and write and needs some form of synchronization.
One example of volatile is the famous double-checked locking, where we avoid synchronization most of the time because the ordering guarantees are all we need:
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
An example where there's absolutely no synchronization involved, is a simple exit flag, here it's not about ordering guarantees but only about the guaranteed visibility
public volatile boolean exit = false;
public void run() {
while (!exit) doStuff();
// exit when exit set to true
}
If another thread sets exit = true the other thread doing the while loop is guaranteed to see the update - without volatile it may not.
x++; operation is atomic?
No. This reduces to x = x + 1. The read of x is atomic, and the write to x is atomic, but x = x + 1 as a whole is not atomic.
I wonder under what circumstances (if any) it is possible to see a variable marked volatile and not see any methods of blocks marked synchronized (that attempt to access/ modify the variable)?
Well, there are all kinds of approaches to concurrency that don't use synchronized. There's a wide variety of other locking utilities in Java, and lock-free algorithms that still require things like volatile: ConcurrentLinkedQueue is a specific example, though it makes extensive use of "magical" compareAndSet atomics.
As a quickly testable example that may illustrate the previous answers, this yields always a final count of 8:
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadTest_synchronize {
public static void main(String[] args) {
ThreadTest_synchronize tt = new ThreadTest_synchronize ();
try {
tt.go();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void go() throws InterruptedException{
MyRunnable t = new MyRunnable();
Thread myThread_1 = new Thread( t, "t1");
Thread myThread_2 = new Thread( t, "t2");
myThread_1.start();
myThread_2.start();
myThread_1.join();
myThread_2.join();
System.out.println("Processing count="+t.getCount());
}
private class MyRunnable implements Runnable{
private AtomicInteger count=new AtomicInteger(0);
#Override
public void run() {
for(int i=1; i< 5; i++){
doSomething(i);
count.getAndAdd(1);
}
}
public AtomicInteger getCount() {
return this.count;
}
private void doSomething(int i) {
try {
Thread.sleep(i*300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
while this generally does not:
public class ThreadTest_volatile {
public static void main(String[] args) {
ThreadTest_volatile tt = new ThreadTest_volatile ();
try {
tt.go();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void go() throws InterruptedException{
MyRunnable t = new MyRunnable();
Thread myThread_1 = new Thread( t, "t1");
Thread myThread_2 = new Thread( t, "t2");
myThread_1.start();
myThread_2.start();
myThread_1.join();
myThread_2.join();
System.out.println("Processing count="+t.getCount());
}
private class MyRunnable implements Runnable{
private volatile int count = 0;
#Override
public void run() {
for(int i=1; i< 5; i++){
doSomething(i);
count++;
}
}
private int add(int count){
return ++count;
}
public int getCount(){
return count;
}
private void doSomething(int i) {
try {
Thread.sleep(i*300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Categories