public class BeSynchronized {
private BeSynchronized() {
}
public static BeSynchronized getInstance() {
return getIns.INSTANCE.returnInstance();
}
public void runBeSynchronized() {
System.out.println("Thread.currentThread().getName() enter = " + Thread.currentThread().getName());
synchronized (this) {
System.out.println("LocalDateTime.now()+Thread.currentThread().getName() = " + LocalDateTime.now() + "~~" + Thread.currentThread().getName() + "=run");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
enum getIns {
INSTANCE;
private BeSynchronized beSynchronized;
getIns() {
beSynchronized = new BeSynchronized();
}
private BeSynchronized returnInstance() {
return beSynchronized;
}
}
}
public class Main {
public static void main(String[] args) {
/**
* synchronized测试
* */
BeSynchronized beSynchronized = BeSynchronized.getInstance();
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
beSynchronized.runBeSynchronized();
}
}, i + "-Thread").start();
}
}
}
G:\jdk\bin\java.exe -javaagent:G:\IDEA\lib\idea_rt.jar=55057:G:\IDEA\bin -Dfile.encoding=UTF-8 -classpath G:\GITHUB\DesignPattern\target\classes Main
Thread.currentThread().getName() enter = 2-Thread
Thread.currentThread().getName() enter = 0-Thread
Thread.currentThread().getName() enter = 4-Thread
Thread.currentThread().getName() enter = 3-Thread
Thread.currentThread().getName() enter = 1-Thread
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:30:42.478178200~~2-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:30:45.490695100~~1-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:30:48.491333~~3-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:30:51.492005100~~0-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:30:54.492464200~~4-Thread=run
Process finished with exit code 0
运行结果可以看到,线程一窝蜂的全都进入runBeSynchronized方法,然后在进入接下来的代码块的时候,被 synchronized(this) 拿住,所以后面的this对象只能等前一个完成之后才能拿到锁,然后再进入代码块运行代码。从运行结果的时间相差3S也反馈了我们预想的结果。
做个对照试验试试,把 synchronized锁 拿掉,然后运行试试。
public void runBeSynchronized() {
System.out.println("Thread.currentThread().getName() enter = " + Thread.currentThread().getName());
// synchronized (this) {
System.out.println("LocalDateTime.now()+Thread.currentThread().getName() = " + LocalDateTime.now() + "~~" + Thread.currentThread().getName() + "=run");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// }
}
G:\jdk\bin\java.exe -javaagent:G:\IDEA\lib\idea_rt.jar=57653:G:\IDEA\bin -Dfile.encoding=UTF-8 -classpath G:\GITHUB\DesignPattern\target\classes Main
Thread.currentThread().getName() enter = 2-Thread
Thread.currentThread().getName() enter = 1-Thread
Thread.currentThread().getName() enter = 3-Thread
Thread.currentThread().getName() enter = 0-Thread
Thread.currentThread().getName() enter = 4-Thread
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:44:55.764253500~~3-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:44:55.764253500~~4-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:44:55.764253500~~0-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:44:55.764253500~~1-Thread=run
LocalDateTime.now()+Thread.currentThread().getName() = 2019-11-12T16:44:55.764253500~~2-Thread=run
Process finished with exit code 0
可以看到代码块没有被锁,全部线程都一拥而上的进行。