I have read posts on thread interleaving and Java thread scheduling, but I don't understand why my two simple Java threads, running against an exclusive Resource, don't to some degree get interleaved access to the Resource.
In the code below, I have a Resource class, with its sole static access() method containing a synchronized block. I simply create and start two MyThread instances in main, each thread with looping repeated calls to Resource.access(). Every access sleeps for 1 sec, then frees the Resource.
public class X {
public static void main(String[] args) {
System.out.println("Creating threads");
Thread t1 = (new Thread(new MyThread()));
System.out.println(String.format("Thread t1 id = %d",
t1.getId()));
Thread t2 = (new Thread(new MyThread()));
System.out.println(String.format("Thread t2 id = %d",
t2.getId()));
System.out.println("Starting threads");
t1.start();
t2.start();
}
}
class MyThread implements Runnable {
@Override
public void run () {
for (int i = 0; i <= 5; i++) {
Resource.access();
}
System.out.println(String.format("Thread %d completed",
Thread.currentThread().getId()));
}
}
class Resource {
private static Object monitor = new Object();
public static void access() {
synchronized (monitor) {
System.out.println(String.format(
"Thread %d accessing resource",
Thread.currentThread().getId()));
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
System.exit(1);
}
System.out.println(String.format(
"Thread %d leaving resource",
Thread.currentThread().getId()));
}
}
}
No matter what I try, however, the loop of the MyThread instance started first (t1 in the above example) completes all accesses to the Resource before the other MyThread instance (t2 in the example above) gets any access to the Resource. Here is the output:
Creating threads
Thread t1 id = 12
Thread t2 id = 13
Starting threads
Thread 12 accessing resource
Thread 12 leaving resource
Thread 12 accessing resource
Thread 12 leaving resource
Thread 12 accessing resource
Thread 12 leaving resource
Thread 12 accessing resource
Thread 12 leaving resource
Thread 12 accessing resource
Thread 12 leaving resource
Thread 12 accessing resource
Thread 12 leaving resource
Thread 13 accessing resource
Thread 12 completed
Thread 13 leaving resource
Thread 13 accessing resource
Thread 13 leaving resource
Thread 13 accessing resource
Thread 13 leaving resource
Thread 13 accessing resource
Thread 13 leaving resource
Thread 13 accessing resource
Thread 13 leaving resource
Thread 13 accessing resource
Thread 13 leaving resource
Thread 13 completed
I read that a Java thread at normal priority may get up to a 1-second time slice, so I would expect Thread 13 above (t2) to have interleaved access to the Resource, not necessarily one for one, but some interleave.