目标 : 理解synchronized的含义、明确synchronized关键字修饰普通方法、静态方法和代码块时锁对象的差异。
synchronized
Java中的关键字,用来实现多线程下的同步机制,避免多个线程的资源访问造成的混乱。
java中每个对象内部都有一个锁,如果一个方法使用 synchronized关键字修饰,java便会把这个方法保护起来。
在其中一个线程释放锁之前,别的线程在调用该同步方法时,会被阻塞。
synchronized修饰普通方法
synchronized修饰普通方法时,使用的锁是对象的锁。
下面是一个示例:
class A {
public synchronized void a() {
}
public synchronized void b() {
}
}
然后创建两个对象
A a1 = new A();
A a2 = new A();
然后在两个线程中并发访问如下代码:
Thread1 Thread2
a1.a(); a2.a();
不能保证同步。
原因:
上面我们创建了两个对象,分别是 a1
,a2
,他们是两个对象,也是就 他们各自有各自的锁, 所以不能保证同步。
synchronized修饰静态方法
synchronized修饰静态方法时,使用的锁是类对象的锁,Class。
如果A的定义是下面这种呢?
class A {
public static synchronized void a() {
}
public static synchronized void b() {
}
}
可以保证同步
原因:
对于static
修饰的方法,它的锁是类对象 即 Xxx.class
即我们调用方法时 都是
A.a()
由于使用的是同一个锁。
线程1Thread1
调用时,线程2Thread2
会被阻塞。 所以可以保证同步
synchronized修饰同步代码块
每个Java对象都有一个锁,线程可以通过进入同步方法获得一个锁,还有另外一种机制,即进入同步方法块获得锁。
synchronized修饰的代码块 使用的锁是对象锁。