非静态方法的锁为this,静态方法锁为Class实例
1、新建Java类演示两个普通同步方法,两个线程打印的顺序。Number非静态方法的锁默认为this,同一个时刻拥有的是同一把锁,打印为one,two
package com.gwolf;
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
}
}
class Number {
public synchronized void getOne() {
System.out.println("one");
}
public synchronized void getTwo() {
System.out.println("tow");
}
}

2、运行程序,查看执行的结果是one,tow,这个结果说明Number非静态方法的锁默认为this,同一个时刻拥有的是同一把锁。

3、现在新增Thread.sleep()给getOne(),Number非静态方法的锁默认为this,同一个时刻拥有的是同一把锁,尽管getOne()方法休眠了三秒,打印还是为one,two
package com.gwolf;
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
}
}
class Number {
public synchronized void getOne() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo() {
System.out.println("tow");
}
}

4、在Number中增加一个普通的方法getThree() ,普通方法没有锁,结果最新打印。
package com.gwolf;
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getThree();
}
}).start();
}
}
class Number {
public synchronized void getOne() {
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("one");
}
public synchronized void getTwo() {
System.out.println("tow");
}
public void getThree() {
System.out.println("three");
}
}

5、查看程序执行结果:three,tow,one。Number非静态方法的锁默认为this,同一个时刻拥有的是同一把锁,首先打印另外一个对象的three,然后打印为one,two

6、在main方法中创建两个对象时是两把同步锁,getOne方法休眠了三秒,所以首先打印的是Two,然后打印one
public static void main(String[] args) {
Number number = new Number();
Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
