I am observing a strange behavior in Java threads where they are seemingly running in a sequential fashion. Following is the code snippet
class ThreadUnsafeClass {
private static int y;
public static void incrementY() {
y++;
}
public static int getY() {
return y;
}
}
public class MultiThreadedClass implements Runnable {
int threadId;
MultiThreadedClass (int threadId) {
this.threadId = threadId;
}
@Override
public void run() {
System.out.println("Number:"+ threadId + ";Thread Unsafe Old Value:" + ThreadUnsafeClass.getY());
try {
if (threadId == 1 || threadId ==2) {
Thread.sleep(60000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUnsafeClass.incrementY();
System.out.println("Number:"+ threadId + ";Thread Unsafe New Value:" + ThreadUnsafeClass.getY());
}
public static void main (String []args) {
MultiThreadedClass thread1 = new MultiThreadedClass(1);
MultiThreadedClass thread2 = new MultiThreadedClass(2);
MultiThreadedClass thread3 = new MultiThreadedClass(3);
MultiThreadedClass thread4 = new MultiThreadedClass(4);
thread1.run();
thread2.run();
thread3.run();
thread4.run();
}
}
Following is the output of the same:
Number:1;Thread Unsafe Old Value:0
Number:1;Thread Unsafe New Value:1
Number:2;Thread Unsafe Old Value:1
Number:2;Thread Unsafe New Value:2
Number:3;Thread Unsafe Old Value:2
Number:3;Thread Unsafe New Value:3
Number:4;Thread Unsafe Old Value:3
Number:4;Thread Unsafe New Value:4
From the above output, it may be noticed that even when threads 1 and 2 are waiting for a reasonable amount of time i.e. 60s threads 3 and 4 still execute only when they have finished executing. Why aren’t the threads executing in parallel and when one thread sleeps, why isn’t the other thread going ahead with its execution? Am I going wrong somewhere?
You need to create a
Threadreferencing theRunnableand callstart(), notrun()on the actual class. Making somethingRunnabledoesn’t mean it’s automatically going to run in a separate thread.e.g.
Why the separation between
RunnableandThread? I can take aRunnableand drop it into a thread pool. The next available thread will run thatRunnable. (e.g. see the Java Executor framework)Runnableonly indicates that an object is available for threading.