One thing not mentioned in the otherwise excellent answers already given is that difference between code1 and code2. In code1, the synchronization is on the instance of the object in which the code is found, and in code2, it's on the specific lock object within the object.
If there's only the two synchronized blocks in the enclosing class, there's no functional difference between the two, but consider this:
class CodeOneClass {
...
synchronized(this) { // or merely "synchronized" - it defaults to this
first protected code block
}
...
synchronized(this) {
second protected code block
}
...
}
class CodeTwoClass {
...
Object lock1 = new Object();
synchronized(lock1) {
first protected code block
}
...
Object lock2 = new Object();
synchronized(lock2) {
second protected code block
}
...
}
If two threads are trying to use the same instance of CodeOneClass, only one of them can be in either of the two protected code blocks at the same time.
But with the second idiom, you have the flexibility to say that it's safe for one thread to be in the first protected block, and another to be in the other. Note that if the locks were the same (both synchronizing on the same lock object), the behavior would be as the first.
There are other differences. Some writers are beginning to point out issues with synchronized(this) - I would point you to another post here on SO:
http://stackoverflow.com/questions/442564/avoid-synchronizedthis-in-java
I highly recommend reading it, and the three posts it links to.