Simple add method Thread safe? - java

Having this simple class, with addition method :
class A {
public Integer add (int a, int b){
return a+b;
}
}
is it thread safe or not..? it looks safe for me, but most poeple answer no, could anyone explain why?

Thread safety should be bothered about only when you have some means of sharing state and you modify that without any locks or synchronization i.e. you modify a shared variable(class level variable) then only you should care about thread safety.
Here there is no issue of thread safety.
And in this particular case each variable is local and that location will not be shared by threads as each function call will have their on separate allocation on stack along with their local variables you should not bother anyways :)

It is completely thread safe, because all variables are local.

Actually that method is not thread safe, but it requires you to know a bit about the internals of the Integer class to understand why. Let's look at some code that yields the same bytecode:
class A {
public Integer add (int a, int b){
// auto boxing hidden in OP's implementation
return Integer.valueOf(a+b);
}
}
For small enough values the Integers are cached and looked up in a array. Using reflection you can access that array and change it's elements. Those changes are not synchronized, therefore if you change those elements, from another thread the result of your method can change too.
The following code should demonstrate the problem on most java VMs: There is a race condition in your method. In most cases it will print 4s and 5s:
import java.lang.reflect.Field;
class A {
public Integer add(int a, int b) {
return a + b;
}
private static volatile boolean cont = true;
public static void main(String[] args) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InterruptedException {
final A a = new A();
new Thread(() -> {
while(cont) {
for (int i = 0; i < 100; i++) {
// print result of add method
System.out.println(a.add(2,2));
}
}
}).start();
// give other thread time to start
Thread.sleep(1);
// mess around with the internals of Integer
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
array[132] = array[133];
cont = false;
}
}
However in most cases nobody messes around with the internals of Integer. If the array in the Integer class is never modified, the values wrapped by the Integer objects returned by your method will always be correct, since the shared state used by Integer.valueOf is never modified. Therefore it would be thread-safe in that case.

Related

Share local variable value between barrier threads in java

I've been working on implementing a custom Cyclic Barrier which adds values passed into the await method and returns the sum to all threads when after notify is called.
The code:
public class Barrier {
private final int parties;
private int partiesArrived = 0;
private volatile int sum = 0;
private volatile int oldSum = 0;
public Barrier(int parties) {
if (parties < 1) throw new IllegalArgumentException("Number of parties has to be 1 or higher.");
this.parties = parties;
}
public int getParties() { return parties; }
public synchronized int waitBarrier(int value) throws InterruptedException {
partiesArrived += 1;
sum += value;
if (partiesArrived != parties) {
wait();
}
else {
oldSum = sum;
sum = 0;
partiesArrived = 0;
notifyAll();
}
return oldSum;
}
public int getNumberWaiting() { return partiesArrived; }
}
This works, but I hear that there is a way to change the values sum and oldSum (or at least oldSum) into local variables of the waitBarrier method. However, after racking my head over it, I don't see a way.
Is it possible and , if yes, how?
However, after racking my head over it, I don't see a way.
Quite so.
Is it possible and , if yes, how?
it is not possible.
For some proof:
Try marking a local var as volatile. It won't work: The compiler doesn't allow it. Why doesn't it? Because volatile is neccessarily a no-op: local vars simply cannot be shared with another thread.
One might think this is 'sharing' a local:
void test() {
int aLocalVar = 10;
Thread t = new Thread(() -> {
System.out.println("Wow, we're sharing it! " + aLocalVar);
});
t.start();
}
But it's some syntax sugar tripping you up there: Actually (and you can confirm this with javap -c -v to show the bytecode that javac makes for this code), a copy of the local var is handed to the block here. This then explains why, in java, the above fails to compile unless the variable you're trying to share is either [A] marked final or [B] could have been so marked without error (this is called 'the variable is effectively final'). Had java allowed you to access non-(effectively) finals like this, and had java used the copy mechanism that is available, that would be incredibly confusing.
Of course, in java, all non-primitives are references. Pointers, in the parlance of some other languages. Thus, you can 'share' (not really, it'll be a copy) a local var and nevertheless get what you want (share state between 2 threads), because whilst you get a copy of the variable, the variable is just a pointer. It's like this: If I have a piece of paper and it is mine, but I can toss it in a photocopier and give you a copy too, we can't, seemingly, share state. Whatever I scratch on my paper won't magically appear on yours; it's not voodoo paper. But, if there is an address to a house on my paper and I copy it and hand you a copy, it feels like we're sharing that: If you walk over to the house and, I dunno, toss a brick through a window, and I walk over later, I can see it.
Many objects in java are immutable (impervious to bricks), and the primitives aren't references. One solution is to use the AtomicX family which are just simplistic wrappers around a primitive or reference, making them mutable:
AtomicInteger v = new AtomicInteger();
Thread t = new Thread(() -> {v.set(10);});
t.start();
t.yield();
System.out.println(t.get());
// prints 10
But no actual sharing of a local happened here. The thread got a -copy- of the reference to a single AtomicInteger instance that lives on the heap, and both threads ended up 'walking over to the house', here.
You can return sum and have the first party clear it:
public synchronized int waitBarrier(int value) throws InterruptedException {
if (partiesArrived == 0) {
sum = 0;
}
partiesArrived++;
sum += value;
if (partiesArrived == parties) {
notifyAll();
} else {
while (partiesArrived < parties) {
wait();
}
}
return sum;
}
Note that the wait condition should always be checked in a loop in case of spurious wakeups. Also, sum doesn't need to be volatile if it's not accessed outside the synchronized block.

Should I synchronize method in my example?

I'm not sure if I should synchronize method methodOne() in my example. I think not but I'm not 100% sure. Could you please give me advice what to do?
public class SynchroIssue {
class Test {
private double a = 0;
void methodOne() {
a++;
}
void go() {
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
methodOne();
System.out.println(Thread.currentThread().getName() + ", a = " + a);
}
}
}).start();
}
}
public static void main(String... args) {
SynchroIssue mainObj = new SynchroIssue();
SynchroIssue.Test object1 = mainObj.new Test();
SynchroIssue.Test object2 = mainObj.new Test();
object1.go();
object2.go();
}
}
Assuming that you are actually going to use instances of the SynchroIssue class concurrently, which you are not doing currently, the answer is yes.
The increment operator is not atomic. It is actually 3 instructions:
Get the current value.
Add 1 to that.
Store new value.
If you are not synchronized, concurrent threads can overlap those steps resulting in strange behavior.
Another option, if you are truly only interested in integers, would be the use of AtomicInteger, which has methods to atomically increment.
object1 and object2 are different objects, each start only one thread, and the variable "a" is private and not static, so "a" are different objects too, and there is no interaction between threads. So there is no need to synchronise methodOne().
In this specific example there's no value to be gained by synchronising the methods because only a single thread ever actually interacts with a given instance.
If you called object1.go() twice you'd have a problem. Using synchronized would not be the best solution to that problem though, you should instead use a java.util.concurrent.atomic.DoubleAccumulator, although AtomicInteger would function just as well given that you start at 0 and only ever increment by 1.
In general, you should be wary of using synchronized to roll your own synchronisation protocols. Prefer instead known thread-safe classes where they're available. java.util.concurrent is a good place to look.
You should, but it wouldn't solve your problem.
If you would synchronize the method, only one thread would be able to increase the variable at a time. But the following System.out.println could still print another value, since by the time you call it, another thread may already have increased a.
The solution for your problem would be, that methodOne would also have to return the variable. Something like this:
synchronized double methodOne() {
return ++a;
}
And the thread should do:
for (int i = 0; i < Integer.MAX_VALUE; i++) {
System.out.println(Thread.currentThread().getName() + ", a = " + methodOne());
}
EDIT: as others already pointed out, you only have to do this if you intend to make the variable static. Otherwise you can leave your code as it is.
I want to add some hints to Brett Okken's answer:
Most of the times, when you have a member variable in your class which is modified by the methods of your class in a concurrent context by more than one thread, you should think about one of the synchronization scopes.
Always go for the smallest available scope of synchronization.
Hope this would be helpful.

Multi-threading program to print numbers from 1 to 50?

im trying to write a program in which two threads are created and the output should be like 1st thread prints 1 and the next thread prints 2 ,1st thread again prints 3 and so on. im a beginner so pls help me clearly. i thought thread share the same memory so they will share the i variable and print accordingly. but in output i get like thread1: 1, thread2 : 1, thread1: 2, thread2 : 2 nd so on. pls help. here is my code
class me extends Thread
{
public int name,i;
public void run()
{
for(i=1;i<=50;i++)
{
System.out.println("Thread" + name + " : " + i);
try
{
sleep(1000);
}
catch(Exception e)
{
System.out.println("some problem");
}
}
}
}
public class he
{
public static void main(String[] args)
{
me a=new me();
me b=new me();
a.name=1;
b.name=2;
a.start();
b.start();
}
}
First off you should read this http://www.oracle.com/technetwork/java/codeconventions-135099.html.
Secondly the class member variables are not shared memory. You need to explicitly pass an object (such as the counter) to both objects, such that it becomes shared. However, this will still not be enough. The shared memory can be cached by the threads so you will have race-conditions. To solve this you will need to use a Lock or use an AtomicInteger
It seems what you want to do is:
Write all numbers from 1 to 50 to System.out
without any number being printed multiple times
with the numbers being printed in order
Have this execution be done by two concurrent threads
First, let's look at what is happening in your code: Each number is printed twice. The reason for this is that i is an instance variable of me, your Thread. So each Thread has its own i, i.e., they do not share the value.
To make the two threads share the same value, we need to pass the same value when constructing me. Now, doing so with the primitive int won't help us much, because by passing an int we are not passing a reference, hence the two threads will still work on independent memory locations.
Let us define a new class, Value which holds the integer for us: (Edit: The same could also be achieved by passing an array int[], which also holds the reference to the memory location of its content)
class Value{
int i = 1;
}
Now, main can instantiate one object of type Value and pass the reference to it to both threads. This way, they can access the same memory location.
class Me extends Thread {
final Value v;
public Me(Value v){
this.v = v;
}
public void run(){
for(; v.i < 50; v.i++){
// ...
}
public static void main(){
Value valueInstance = new Value();
Me a = new Me(valueInstance);
Me b = new Me(valueInstance);
}
}
Now i isn't printed twice each time. However, you'll notice that the behavior is still not as desired. This is because the operations are interleaved: a may read i, let's say, the value is 5. Next, b increments the value of i, and stores the new value. i is now 6. However, a did still read the old value, 5, and will print 5 again, even though b just printed 5.
To solve this, we must lock the instance v, i.e., the object of type Value. Java provides the keyword synchronized, which will hold a lock during the execution of all code inside the synchronized block. However, if you simply put synchronize in your method, you still won't get what you desire. Assuming you write:
public void run(){ synchronized(v) {
for(; v.i < 50; v.i++) {
// ...
}}
Your first thread will acquire the lock, but never release it until the entire loop has been executed (which is when i has the value 50). Hence, you must release the lock somehow when it is safe to do so. Well... the only code in your run method that does not depend on i (and hence does not need to be locking) is sleep, which luckily also is where the thread spends the most time in.
Since everything is in the loop body, a simple synchronized block won't do. We can use Semaphore to acquire a lock. So, we create a Semaphore instance in the main method, and, similar to v, pass it to both threads. We can then acquire and release the lock on the Semaphore to let both threads have the chance to get the resource, while guaranteeing safety.
Here's the code that will do the trick:
public class Me extends Thread {
public int name;
final Value v;
final Semaphore lock;
public Me(Value v, Semaphore lock) {
this.v = v;
this.lock = lock;
}
public void run() {
try {
lock.acquire();
while (v.i <= 50) {
System.out.println("Thread" + name + " : " + v.i);
v.i++;
lock.release();
sleep(100);
lock.acquire();
}
lock.release();
} catch (Exception e) {
System.out.println("some problem");
}
}
public static void main(String[] args) {
Value v = new Value();
Semaphore lock = new Semaphore(1);
Me a = new Me(v, lock);
Me b = new Me(v, lock);
a.name = 1;
b.name = 2;
a.start();
b.start();
}
static class Value {
int i = 1;
}
}
Note: Since we are acquiring the lock at the end of the loop, we must also release it after the loop, or the resource will never be freed. Also, I changed the for-loop to a while loop, because we need to update i before releasing the lock for the first time, or the other thread can again read the same value.
Check the below link for the solution. Using multiple threads we can print the numbers in ascending order
http://cooltekhie.blogspot.in/2017/06/#987628206008590221

Starting a thread as the last statement of the constructor of a final class

I understand that in general it is a bad idea to start a new thread in a constructor because it could let this escape before it is fully constructed. For example:
public final class Test {
private final int value;
public Test(int value) throws InterruptedException {
start();
this.value = value;
}
private void start() throws InterruptedException {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Construction OK = " + Boolean.toString(Test.this.value == 5));
}
}).start();
}
}
public static void main(String[] args) throws InterruptedException {
Test test = new Test(5);
}
}
This prints (obviously not the same every run):
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = true
Construction OK = true
Construction OK = true
Now IF the start method is the last statement of the constructor AND reordering is prevented by using a synchronized block around the final value initialisation, is there still a risk associated with starting threads from the constructor?
public Test(int value) throws InterruptedException {
synchronized (new Object()) { // to prevent reordering + no deadlock risk
this.value = value;
}
start();
}
EDIT
I don't think this has been asked before in the sense that the question is more specific than just "Can I start threads in a constructor": the threads are started in the last statement of the constructor which means the object construction is finished (as far as I understand it).
Yes there is, because Test could be subclassed and then start() will be executed before the instance is created. The subclasses constructor may have something more to do.
So the class should be final at least.
In this particular case I would consider marking value as volatile (or use AtomicBoolean) and start the threads after the value is set:
this.value = value; // this.value.set(value) if using AtomicBoolean
start();
If going for this slightly dodgy solution, I would make the class final as well, to avoid the problem described by Andreas_D.
Regarding your edit:
[...] which means the object construction is finished (as far as I understand it).
That's right, but consider the following scenario:
Your test-threads are slightly more complex, and accesses a list testList of tests. Now if you do
testList.add(new Test());
the thread started in the constructor may not find the associated test in the list, because it has not yet been added. This is avoided by instead doing
Test t = new Test();
testList.add(t);
t.start();
Related question:
calling thread.start() within its own constructor
In the constructor you call the start method by
start()
of the class. Now you can notice that the method you are calling is of an object of this class which has not been create yet. So you are still passing a reference of an unconstructed object to a method. You have included the methodcall itself in the creation of the object, while any method of an object should be called after the object is constructed completely.
So still there is risk associated with it.
Also it was really a very good question.
The synchronized(new Object()) does NOT prevent reordering - because the monitor is a local variable, the compiler is actually free to ignore the synchronized block.
In particular, the compiler can prove that it is impossible that two threds would lock on the same monitor (by definition of local variables) and that the synchronized block is therefore redundant and can be ignored.

Is it possible to update an attribut within a thread

Let say that I create an object and run it in a thread, something like this.
public class Main {
public static void main(String[] args) {
SomeClass p = new SomeClass (143);
p.start();
p.updateNumber(144);
}}
Is it possible to update the parameter passed in SomeClass with a methode updateNumber() as fallows:
# Updated
class SomeClass extends Thread {
volatile int number ;
SomeClass (int number ) {
this.number = number ;
}
public void run() {
while(true){
System.out.println(number);
}
}
public void updateNumber(int n){
number =n;
}
}
Result :
144
144
144
144
144
...
Thanks
Yes, but you need to declare number as volatile, or (preferably) use an AtomicLong instead of a long.
Declare number as volatile.
When is volatile needed ?
When multiple threads using the same
variable, each thread will have its
own copy of the local cache for that
variable. So, when it's updating the
value, it is actually updated in the
local cache not in the main variable
memory. The other thread which is
using the same variable doesn't know
anything about the values changed by
the another thread. To avoid this
problem, if you declare a variable as
volatile, then it will not be stored
in the local cache. Whenever thread
are updating the values, it is updated
to the main memory. So, other threads
can access the updated value
One other option not mentioned and which is the option you should use instead of synchronization as mentioned above is the make use of the Concurrency package introduced by Doug Lee in Java 1.5.
Use the Atomic classes, these take care of all you concurrency woes. (well to a point)
Something like this:
private AtomicInteger number = new AtomicInteger(0);
public void updateNumber(int n) {
number.getAndSet(n);
}
public int getNumber() {
return number.get();
}
Java 1.6 AtomicInteger JavaDoc
Java Concurrency in Practice
In my opinion the Java Concurrency in Practice is the best book on threading in Java
SomeClass even it is Runnable, it is just a normal class and objects of it can be accessed by any thread that has reference to it. In your example. you are not calling updateNumber() form anywhere, but if you call it after p.start(), you are acessing it from the thread that actually made the instance. If you are calling updateNumber() in run(), then you are accessing it from the thread you've just started.
The other question is: is it safe in your setup to change it form multiple threads? the answer is no. You have to declare it as volatile (let say), or synchronize if you changing it based on current value. How and what to synchronize depends on what you are actually doing with it.
You can use the keyword volatilewhen all the following criteria are met:
Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value
The variable does not participate in invariants with other state variables
Locking is not required for any other reason while the variable is being accessed
Otherwise, I'd recommend using some sort of synchronization policy
class SomeClass implements Runnable {
private Integer number;
SomeClass (int number) {
this.number = Integer.valueOf(number);
}
#Override
public void run() {
while(true){
System.out.println(getNumber());
}
}
public void updateNumber(int n){
synchronized(number){
number = Integer.valueOf(n);
}
}
public int getNumber(){
synchronized(number){
return number.intValue();
}
}
}
Yes, you can just call p.updateNumber(...) but you will need to be careful of thread synchronization issues.

Categories

Resources