Method vs Class Variables When Multithreading
I had to recently refresh my memory of basic computer science, so I'll note it here as well. While executing a method on a shared object across threads, we need not concern ourselves with races manipulating the variables declared within the method. All the method variables are created on a separate chunk of the stack for each invocation.
Class variables on the other hand are not pushed onto the stack for each method invocation on a shared object, so access to these do need to be synchronized.
Method variables within static methods do not offer any exceptions, they are still pushed onto the stack, hence isolated from other concurrent invocations. Static methods may only access class variables that are static as well, so it should be noted that these static class variables are shared even more widely -- across all instances of this class.
I used this test code to prove this behavior to myself:
import java.io.*; import java.util.*; public class Test implements Runnable { Test callback; String name; int sleep; String shared; public static void main(String[] args) { new Test(); } public Test() { Runnable r1 = new Test(2000, "t1", this); Runnable r2 = new Test(2000, "t2", this); Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); try { Thread.sleep(1000); } catch (Exception ex) { ex.printStackTrace(); } t2.start(); } public Test(int s, String n, Test cb) { sleep = s; name = n; callback = cb; } public void doIt(int sleep, String value) { System.out.println(value + " started and set values to " + value); String ret = value; shared = value; try { Thread.sleep(sleep); System.out.println(value + " sleeping"); } catch (Exception ex) { ex.printStackTrace(); } System.out.println(value + "'s local ret: " + ret); System.out.println(value + "'s shared: " + shared); } public void run() { callback.doIt(sleep, name); } }
The output is:
t1 started and set values to t1 t2 started and set values to t2 t1 sleeping t1's local ret: t1 t1's shared: t2 t2 sleeping t2's local ret: t2 t2's shared: t2