Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safety of method parameters in Java

I would like to know if thread safety already plays a role when handling parameters of members in Java.

Say you have a method of an API

boolean moreThanTen(long value) {
    if(value > 10) return true;
    else return false;
}

would this method be thread safe?

I imagine it would since every thread has its own stack for local variables, and primitives are all stored in this local stack.

The only thing that makes me unsure is the fact that a long would be two separate reads and thus is generally not thread safe.

My question is: can I be sure that the parameter of a method gets copied atomically? So when using a primitive as a parameter (even float/long) can I be sure that during copying it to a local variable thread safety won't be an issue?

like image 238
Xtroce Avatar asked Jun 27 '16 15:06

Xtroce


2 Answers

To be thread un-safe, a method needs to allow more than one thread to access shared resources (e.g. a field).

In your example there are no shared resources (java passes arguments by value) so the method cannot be unsafe.

This one would be unsafe because threshold is accessible from more than one thread and accesses to the variable are not correctly synchronized:

  • a thread may be reading the threshold variable while it's being updated by another thread, which may result in an inconsistent read (long writes are not guaranteed to be atomic); and
  • a write to the threshold variable from one thread may not be visible from another thread due to the lack of synchronization, which may result in the second thread reading a stale value.
private long threshold; //mutable, may change

boolean moreThanThreshold(long value) {
  return value > threshold; //side comment: cleaner than your if/else
}
void setThreshold(long t) { this.threshold = t; }
like image 74
assylias Avatar answered Nov 09 '22 19:11

assylias


No issues of threading in this case.. all reads are happening in the methods own stack. In short even though they are two reads.. they are happening on a value inside stack which is not shared among other threads.

Here is bit more detail on why two reads are not a problem.

When passing arguments to a method we ARE NOT passing the reference variable, but a copy of the bits in the reference variable. Something like this: 3bad086a. 3bad086a represents a way to get to the passed object. So we're just passing 3bad086a that it's the value of the reference. We're passing the value of the reference and not the reference itself (and not the object). This value is actually COPIED and given to the method. We always pass a copy of the bits of the value of the reference! If it's a primitive data type these bits will contain the value of the primitive data type itself. If it's an Object the bits will contain the value of the address that tells the JVM how to get to the Object.

like image 34
Gaurava Agarwal Avatar answered Nov 09 '22 17:11

Gaurava Agarwal