Understanding thread behavior

B

bobroberts_333

I've taken a "deadlock" sample from a java Sun tutorial page and
modified it slightly. It's exhibiting some behavior that I find
unexpected.

Here is the sample code. Keep in mind that it's supposed to deadlock.

public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void step1(Friend thefriend) {
System.out.println(this.name + " : locked by: " +
this.name);
System.out.println(this.name + " : trying to get lock
on: " + thefriend.getName());
thefriend.step2(this);
System.out.println(this.name + " : released lock on: " +
thefriend.getName());
}
public synchronized void step2(Friend thefriend) {
System.out.println(this.name + " : locked by " +
thefriend.getName());
}
}

public static void main(String[] args) {

System.out.println("There are two separate locks involved
here.");
System.out.println("One lock is for the 'Bob' object, and one
for the 'Roberts' object");
System.out.println("");

final Friend bob = new Friend("Bob");
final Friend roberts = new Friend("Roberts");

new Thread(new Runnable() {
public void run() { bob.step1(roberts); }
}).start();

new Thread(new Runnable() {
public void run() { roberts.step1(bob); }
}).start();
}
}


Note the three System calls in main. If the System calls are present,
the code will execute and NO deadlock will occur (95% of the time...).
If I take out the System calls, the deadlock occurs as expected nearly
100% of the time.

I don't know much about JVMs and Java in general. This was a learning
exercise. Can someone give me a
reasonable explanation of why adding the System calls before any
objects are even created, might cause timing
issues that would throw off the deadlock?

I'm a bit at a loss here...

Any input is appreciated. Thanks!

-Bob
 
B

bobroberts_333

I think I've got my own answer here. I think the System calls are
causing timing differences later in the program because
of context switching in the OS. The process is probably getting
switched out and changing the time slice remaining for
the process enough that subsequent switches occur at different
locations during code execution. If I remember correctly,
the time slice on Solaris (on which I'm running this) is 100ms.

If anyone else has any ideas, please feel free to add them...

Thanks.
 
T

Tom Hawtin

I think I've got my own answer here. I think the System calls are
causing timing differences later in the program because
of context switching in the OS. The process is probably getting
switched out and changing the time slice remaining for
the process enough that subsequent switches occur at different
locations during code execution. If I remember correctly,
the time slice on Solaris (on which I'm running this) is 100ms.

It's quite possibly the loading of code in java.io (and potentially
other compiling) taking time. If you do it at the start of main, it has
all happened before you start your threads. If you don't your first
thread grabs a lock, and then spends time dawdling, in which time the
other thread can grab the other lock first.

The strange effects with having compilers threads and on stack
replacement. You should also note that multicore (or multiprocessor)
machines may behave (i.e. deadlock) differently. Software developed on a
multicore machine may start deadlocking on single core machine, and vice
versa.

So, "it looks alright to me" and "it works on my PC" are not good enough
excuses...

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,787
Messages
2,569,627
Members
45,328
Latest member
66Teonna9

Latest Threads

Top