理解java中的synchronized关键字

目标:

理解synchronized含义、明确synchronized关键字修饰普通方法、静态方法、和代码块时锁对象的差异
有如下一个类A

class A {
    public synchronized void a() {
    }

    public synchronized void b() {
    }
}

然后创建两个对象

A a1 = new A();
A a2 = new A();

然后在两个线程中并发访问如下代码:

Thread1                       Thread2
a1.a();                       a2.a();

请问二者能否构成线程同步?
如果A的定义是下面这种呢?

class A {
    public static synchronized void a() {
    }

    public static synchronized void b() {
    }
}

答案:

第一种不会同步,锁的是A的实例对象(this),a1,a2是两个不同的实例,不同线程的不同对象访问不会同步;第二种可以同步,修饰静态方法,锁的是类对象(this.class),a1和a2的同步锁一样,所以可以同步。

分析:

Synchronized是java中的关键字,是一种同步锁,用来实现多线程的同步机制,保证同一时间只有一个线程可以操作对应资源。可以修饰方法、代码块


Synchronized的机制:
Synchronized在实现同步的时候会声明一把锁,表明必须持有这把锁的线程才能访问执行,在一个线程需要执行这块代码时,会先尝试持有这把指定的锁,如果这个锁已经被别的线程持有,那么该线程就会开始等待,知道这把锁被释放后才会继续执行,并且在执行时会一直持有这把锁,以防止其他线程进入这把锁控制的代码,直到该线程执行完才会释放锁


Synchronized修饰对象有三种:

  1. 修饰普通方法 此时加锁的方法只允许一个线程访问,但是这种情况下锁的是该方法的实例对象(即题中Anew出来的对象),如果多个线程不同的对象访问该方法,则无法保证同步。
  2. 修饰静态方法 静态方法是类方法,所以此时锁的是包含这个方法的类(即A.class),也就是类对象,这种情况下,多个线程不同对象访问该静态方法,也是可以保证同步的
  3. 修饰代码块 修饰普通代码块同步效果跟修饰普通方法一样,修饰静态代码块同步效果和修饰静态方法类似

参考星球伙伴回答

猜你喜欢

转载自blog.csdn.net/xj531/article/details/80734157