4

I have a static variable that I would like to be unique per thread.

Is this the case for all static variables? Or can it not be guaranteed. That is, will threads occasionally update the static variable's value in the main memory, or keep it to themselves?

If this cannot be guaranteed, is there any type of variable in Java that is both static and thread-unique? Something essentially global to a thread, but hidden from other threads?

Makoto
  • 104,088
  • 27
  • 192
  • 230
stuart
  • 1,785
  • 2
  • 26
  • 38
  • 3
    This is precisely what [`ThreadLocal`](http://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html) is for. Although I would be curious to know what you are storing in this static variable and why you believe you need a unique one for each thread. – Sean Bright Jul 07 '15 at 18:59

2 Answers2

19

I think what you are looking for is Java's ThreadLocal.

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.

Mind you, if you do thread pooling this may cause problems for you since you may think you are getting a new thread, in terms of it starting a new process, but what is happening is that you are reusing a thread that finished working on other data and thus has left-overs and these are hard to debug when they occur in the wild.

Here is a tutorial on using ThreadLocal.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Sled
  • 18,541
  • 27
  • 119
  • 168
  • wow that coused me very big issues because the thread pool reused old threads from old tasks, till i understood what going on. – CMS Jun 07 '18 at 23:19
5

static variables are shared among threads.

If you want your variable to be unique per thread, you may want to use ThreadLocal:

 // Atomic integer containing the next thread ID to be assigned
 private static final AtomicInteger nextId = new AtomicInteger(0);

 // Thread local variable containing each thread's ID
 private static final ThreadLocal<Integer> threadId =
     new ThreadLocal<Integer>() {
         @Override protected Integer initialValue() {
             return nextId.getAndIncrement();
     }
 };
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • 1
    The atomic integer is not thread local. this allows you to thread safe get and increment the value it contains. – LhasaDad Jul 07 '15 at 19:11
  • Is it guaranteed that a static variable will be shared among threads? Responses to this question imply not: http://stackoverflow.com/questions/2423622/volatile-vs-static-in-java/12193970 "update made by t1 to the static variable in its local cache wont reflect in the static variable for t2 cache" where t1 and t2 are threads – stuart Jul 07 '15 at 19:14
  • 1
    @stuart I believe its guaranteed to be shared _but_ isn't not guaranteed to be continually updated unless you declare it `volatile`. Essentially, a thread is allowed to cache it for a while and I'm sure of the guarantees around it. – Sled Jul 07 '15 at 19:18
  • ... and because a `ThreadLocal` is not shared among multiple threads (by definition), there are no memory visibility issues when using them correctly. – Sean Bright Jul 07 '15 at 19:19
  • 1
    @ArtB did you mean to say "isn't not"? also is there a missing "not" there: "...and i'm *not?* sure of the guarantees around it." – stuart Jul 07 '15 at 19:19
  • The short answer is this: any variable (instance OR static - it does not matter) that is accessed by multiple threads needs appropriate synchronization to avoid memory visibility issues. – Sean Bright Jul 07 '15 at 19:23
  • 1
    @stuart yes, that's what I meant. – Sled Jul 07 '15 at 19:23