5

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?

giannis christofakis
  • 8,201
  • 4
  • 54
  • 65
Xtroce
  • 1,749
  • 3
  • 19
  • 43

2 Answers2

8

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; }
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Your example is thread safe because individual reads and writes are atomic. You have demonstrated a visibility problem, which can be fixed by using volatile, which will also eliminate word tearing (on JLS compliant JVMs) –  Jun 28 '16 at 05:29
  • If there is a visibility problem, by definition, the method is not thread safe. Additionally, a long write is *not* guaranteed to be atomic by the JLS. – assylias Jun 28 '16 at 07:34
  • A *volatile* long write is –  Jun 28 '16 at 07:34
  • @xTrollxDudex I know - you said "*Your example is thread safe because individual reads and writes are atomic*" - that is incorrect. – assylias Jun 28 '16 at 07:37
  • I meant that it isn't unsafe *because* you cannot read the value of threshold (given that it is volatile as I stated) while it is being updated, but because it is not volatile. My point is that the read and write of `threshold` cannot be interleaved. –  Jun 28 '16 at 07:39
  • I'm not sure I completely follow you but I have added some clarifications. – assylias Jun 28 '16 at 07:45
1

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.

Gaurava Agarwal
  • 974
  • 1
  • 9
  • 32