synchronized is always locking on an object. In case of a synchronized method, the object is this. So basically these two methods do the same:
synchronized public void method1() {
// do something
}
and
public void method1() {
synchronized(this){
// do something
}
}
As long as one thread has the lock on the lock object, no other thread can lock this object. So in your example, the synchronized methods (one, two and three) can never be executed at the same time. method4 is not synchronized, so it can access the object anytime.
If you want a more fine-grained locking, because method1and method2 should be exclusive and method3and method4 you could use for example something like this:
class Sample{
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void method1(){
synchronized(lock1) {
// do something
}
}
public void method2(){
synchronized(lock1) {
// do something
}
}
public void method3(){
synchronized(lock2) {
// do something
}
}
public void method4(){
synchronized(lock2) {
// do something
}
}
}
You can then even use the synchonized(lock) method to just wrap the statements that need to be synchronized, not the whole method:
public void method() {
// some code
synchronized(lock) {
// code that must be synchronized
}
// some other code
}
With this approach you can keep the lock duration to a minimum.