同步方法锁的是当前实例对象: 锁的是 -->test
/**
* 普通同步方法(锁的是当前实例对象)
**/
private synchronized void method1(String name) {
try {
System.out.println(name);
System.out.println("do some thing!!!");
Thread.sleep(5000);
System.out.println("sleep over!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//创建类对象并实例化
SynchronizedTest test = new SynchronizedTest();
SynchronizedTest test2 = new SynchronizedTest();
new Thread(() -> {
test.method1("first::>" + Thread.currentThread().getName());
}).start();
new Thread(() -> {
test.method1("second::>" + Thread.currentThread().getName());
}).start();
}
输出结果与分析:
synchronized 锁的是:test
SynchronizedTest test = new SynchronizedTest() 实例化的对象test。
程序是顺序执行的,所以线程0先拿到method1的锁然后执行打印
first::>Thread-0
do some thing!!!
然后休眠5秒钟后打印
sleep over!
线程0释放method1的锁,然后线程1拿到method1的资源
second::>Thread-1
do some thing!!!
然后休眠5秒钟然后打印后面的
sleep over!
如果将第二个thread 换成 test2.method1()。(自己的打印结果可能和这个有出入)
同步方法块:锁的也是 --> test 运行结果同上
/**
* 同步方法块
**/
private void method2(String name){
synchronized (this){
try {
System.out.println(name);
System.out.println("do some thing!!!");
Thread.sleep(5000);
System.out.println("sleep over!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
//创建类对象并实例化
SynchronizedTest test = new SynchronizedTest();
new Thread(() -> {
test.method2("first::>" + Thread.currentThread().getName());
}).start();
new Thread(() -> {
test.method2("second::>" + Thread.currentThread().getName());
}).start();
}
静态同步方法 --> 锁是当前类的class对象 运行结果同上
/**
* 静态同步方法
**/
private synchronized static void method3 (String name) {
try {
System.out.println(name);
System.out.println("do some thing!!!");
Thread.sleep(5000);
System.out.println("sleep over!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Thread(() -> {
SynchronizedTest.method3("first::>" + Thread.currentThread().getName());
}).start();
new Thread(() -> {
SynchronizedTest.method3("second::>" + Thread.currentThread().getName());
}).start();
}