目录标题
方法(静态方法/实例方法)
修饰静态方法(锁当前类):对当前类的Class对象加锁
public class SynchronizedDemo {
// 修饰普通方法(实例方法)
public synchronized void instanceMethod() {
// TODO 业务逻辑
}
public static void main(String[] args) {
SynchronizedDemo obj1 = new SynchronizedDemo();
SynchronizedDemo obj2 = new SynchronizedDemo();
new Thread(() ->{
obj1.instanceMethod(); //多线程访问加锁普通实例方法,互不影响
}).start();
new Thread(() ->{
obj2.instanceMethod();
}).start();
}
}
普通方法作用范围是对象实例,不可跨对象,所以多个线程不同对象实例访问此方法,互不影响,无法产生互斥。
修饰实例方法(锁当前对象实例):对当前实例对象this加锁
public class SynchronizedDemo {
// 修饰静态方法(类方法)
public synchronized static void staticMethod() {
// TODO 业务逻辑
}
public static void main(String[] args) {
new Thread(() ->{
SynchronizedDemo.staticMethod(); //多线程访问加锁静态方法,互斥
}).start();
new Thread(() ->{
SynchronizedDemo.staticMethod();
}).start();
}
}
静态方法是通过类访问,是类级别的跨对象的,所以锁的范围是针对类,多个线程访问互斥。
修饰代码块(锁指定对象/类)
synchronized(类.class) 表示进入同步代码前要获得 给定 Class 的锁
public class SynchronizedDemo {
// 代码块锁(类):锁的应用对象是User类,可以称之为类锁
public void method2() {
synchronized (User.class) {
// TODO 业务逻辑
}
}
public static void main(String[] args) {
SynchronizedDemo obj1 = new SynchronizedDemo();
SynchronizedDemo obj2 = new SynchronizedDemo();
new Thread(() ->{
obj1.method2(); //代码块锁,后面是类,多线程访问互斥
}).start();
new Thread(() ->{
obj2.method2();
}).start();
}
虽然是通过对象访问的此方法,但是加锁的代码块是类级别的跨对象的,所以锁的范围是针对类,多个线程访问互斥。
synchronized(object) 表示进入同步代码库前要获得 给定对象的锁。
public class SynchronizedDemo {
// 代码块锁(对象实例):锁的应用对象是当前对象实例,可以称之为对象锁
public void method1() {
synchronized (this) {
// TODO 业务逻辑
}
}
public static void main(String[] args) {
SynchronizedDemo obj1 = new SynchronizedDemo();
SynchronizedDemo obj2 = new SynchronizedDemo();
new Thread(() ->{
obj1.method1(); //代码块锁,后面是对象,多线程访问互不影响
}).start();
new Thread(() ->{
obj2.method1();
}).start();
}
}
作用范围是对象实例,不可跨对象,所以多个线程不同对象实例访问此方法,互不影响,无法产生互斥。
demo来源:synchronized锁(方法锁, 代码块锁)