How to maintain state for each thread separately

I have an int x field, which is supposed to be accessed by many threads at the same time. I want x have a separate copy for each thread, each of which starts with the original value. I tried to do this using the volatile keyword, but each new thread still changes x for the other threads.

Here is a sample code:

 public class StackOverflowThread0 { public StackOverflowThread0() { new A().start(); } public static void main(String[] args) { new StackOverflowThread0(); } volatile int x = 0;//<--keep original for each thread? class A extends Thread { @Override public void run() { try { while (true) { getT().start(); Thread.sleep(1000); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } Thread getT() { Thread t = new Thread() { @Override public void run() { x++; for (int i = 0; i < 100; i++) { try { System.out.println("x=" + x + " | thread id=" + Thread.currentThread().getId() + "| 100*x+x=" + (100 * x + x)); Thread.sleep(100); } catch (InterruptedException ex) { ex.printStackTrace(); } } interrupt(); } }; return t; } } 

output:

 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 x=1 | thread id=10| 100*x+x=101 //thread 10 has x field value as 1 x=2 | thread id=11| 100*x+x=202 //thread 11 modifies x field to 2 x=2 | thread id=10| 100*x+x=202 //thread 10 lost x value as 1 :( etc... 

How to save a separate x value for each thread, or is there a better way to solve the problem?

+7
java multithreading
source share
2 answers

The ThreadLocal class can do this for you. It maintains a variable that is different for each thread that accesses it. In other words, each thread gets its own unique copy of the variable.

Check the following code codes:

 //Initialisation of the variable. Here an initial value of zero is assigned. ThreadLocal<Integer> x = ThreadLocal.withInitial(()-> 0); //Incrementing the value by one: x.set(x.get() + 1); //Outputting the result: System.out.println("x=" + x.get() + " | thread id=" + Thread.currentThread().getId() + "| 100*x+x=" + (100 * x.get() + x.get())); 

Edit: for those using 1.7, there really is a way to use ThreadLocal without a lambda expression. However, you will have to override the initialValue () method.

 ThreadLocal<Integer> x = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return 0; } }; 
+4
source share

An alternative to local thread storage, you can save your variable x in the call stack. Of course, it depends on how you use x ; you may need your variable on the heap. And in this case, you're better off with ThreadLocal.

All threads share a heap, but have their own stack .

This means that any variables that are stored on the stack are immediately local.

+3
source share

All Articles