synchronized关键字

一,synchronized的特性

  1. 互斥性(Mutual Exclusion):synchronized 可以保证同一时间只有一个线程可以执行被 synchronized 修饰的方法或代码块。其他线程必须等待当前线程执行完成后才能访问。

  2. 可见性(Visibility):synchronized 会确保在进入同步块之前,线程会从主存中刷新共享变量的值,而在退出同步块时,会将修改后的值刷新到主存中。这样可以保证多个线程看到的是同一份最新的数据。

  3. 有序性(Ordering):synchronized 不仅保证了互斥性和可见性,还具有有序性的特性。也就是说,在多个线程并发执行的情况下,通过 synchronized 保护的代码块的执行结果是按照一定的顺序来排列的,而不会出现乱序的情况。

  4. 原子性(Atomicity):synchronized 保证了被它修饰的方法或代码块作为一个整体的执行是原子的,不会被其他线程中断。即使 synchronized 修饰的方法或代码块中包含多个操作,它们也会被当作一个不可分割的单元来执行。

二,synchronized的使用

修饰方法:在方法声明时加上 synchronized 关键字,这意味着整个方法都是同步的。例如:

public synchronized void method() {
    // 同步代码块
}

修饰代码块:使用 synchronized 关键字来修饰一段代码块,这样只有当线程获得了该代码块的锁时才能执行这段同步代码块。例如:

public void method() {
    synchronized (this) {
        // 同步代码块
    }
}

修饰类:使用 synchronized 关键字来修饰整个类,这意味着该类的所有静态方法都是同步的,也就是说只有一个线程能够访问该类的静态方法。例如:

public class MyClass {
    public static synchronized void method1() {
        // 静态同步方法
    }

    public static synchronized void method2() {
        // 静态同步方法
    }
}

三,synchronized的锁机制

`synchronized` 关键字使用的是内置锁(Intrinsic Lock)或者称为监视器锁(Monitor Lock),它是Java中的一种基本锁机制。

当线程进入一个被 `synchronized` 修饰的方法或代码块时,它会尝试获取该方法或代码块所对应的对象的内置锁。如果该锁没有被其他线程占用,那么该线程就会成功获取到锁,并执行同步代码块;如果该锁已经被其他线程占用,那么该线程就会进入阻塞状态,直到获取到锁才能继续执行。

内置锁具有以下特性:

1. 独占性:内置锁是一种独占锁,每次只能有一个线程获得锁,其他线程必须等待。

2. 可重入性:同一个线程可以多次获取同一个锁而不会发生死锁。线程每次获取锁时,会将锁的持有计数加一,释放锁时,会将计数减一,只有计数为零时才真正释放锁。

3. 公平性:内置锁是非公平的,也就是说,当多个线程都在等待获取锁时,不保证按照先来先得的顺序分配锁。

4. 阻塞等待:如果一个线程尝试获取锁时发现锁已经被其他线程占用,那么它会进入阻塞状态,直到锁被释放。

5. 通知等待:当一个线程获取到锁并执行完同步代码块后,会释放锁并通知其他等待的线程,从而使它们有机会获取到锁并执行。

需要注意的是,`synchronized` 关键字只能对同一个对象进行加锁,因为它是以对象为单位的。如果需要对多个对象进行加锁,可以考虑使用 `Lock` 接口的实现类,如 `ReentrantLock`。

你可能感兴趣的:(java,jvm,开发语言)