普通方法上
- synchronized 在普通方法上为对象锁,不通对象调用时不会阻塞,相同对象调用时为同步阻塞。示例如下:
public class Task {
public synchronized void funA(){
System.out.println("======== start running funA ... ========");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("======== end running funA ... ========");
}
public synchronized void funB(){
System.out.println("======== start running funB ... ======== ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("======== end running funB ... ======== ");
}
public static void main(String[] args) {
for (int i=0; i<3;i++){
new Thread(() -> new Task().funA()).start();
}
for (int i=0; i<3;i++){
new Thread(() -> new Task().funB()).start();
}
Task task = new Task();
for (int i=0; i<3;i++){
new Thread(() -> task.funA()).start();
}
for (int i=0; i<3;i++){
new Thread(() -> task.funB()).start();
}
}
}
代码块
- synchronized(Task.class)为类锁,则无论是都相同对象调用都为同步阻塞.
- synchronized(this)为对象锁,不通对象调用时不会阻塞,相同对象调用时为同步阻塞。
public class Task {
public void funC(){
synchronized(Task.class) {
System.out.println("======== start running funC ... ========");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("======== end running funC ... ========");
}
}
public void funD(){
synchronized(this) {
System.out.println("======== start running funD ... ========");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("======== end running funD ... ========");
}
}
public static void main(String[] args) {
for (int i=0; i<3;i++){
new Thread(() -> new Task().funC()).start();
}
for (int i=0; i<3;i++){
new Thread(() -> new Task().funD()).start();
}
}
}
静态方法上
- synchronized在静态方法上为对象锁,无论是否同一对象都为同步阻塞
public class Task {
public static synchronized void funE(){
System.out.println("======== start running funE ... ========");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("======== end running funE ... ========");
}
public static synchronized void funF(){
System.out.println("======== start running funF ... ======== ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("======== end running funF ... ======== ");
}
public static void main(String[] args) {
for (int i=0; i<3;i++){
new Thread(() -> new Task().funE()).start();
}
Task task = new Task();
for (int i=0; i<3;i++){
new Thread(() -> task.funF()).start();
}
}
}
总结
- 对象锁:同一个对象下是同步阻塞的,不同对象之间非阻塞的。
- 类锁:无论是否为相同对象均为同步阻塞。
- 同一个类多个方法被synchronized修饰/代码块/静态方法,则在各个方法之间也是同步阻塞的。