跳至主要內容

Synchronized


Synchronized

synchronized介绍

在Java中,synchronized是一种内置的对象锁,可以用于保护共享资源的并发访问。synchronized可以修饰方法和代码块,其作用是在同一时刻只允许一个线程进入被synchronized修饰的方法或代码块,其他线程必须等待锁的释放才能访问该方法或代码块。

synchronized有以下几个特点:

  1. 可重入性:如果一个线程已经获得了一个对象的锁,那么它可以重复获得该对象的锁。
  2. 可见性:在一个线程释放锁之前,它对共享变量的修改对其他线程是可见的。
  3. 原子性:synchronized保证了对共享变量的操作是原子性的,即一个线程在修改共享变量时,其他线程无法访问该变量,从而避免了数据竞争和一致性问题。

synchronized的使用有以下几个注意点:

  1. 一般建议将synchronized用于保护共享资源的访问,而不是用于保护方法的所有代码,以减少锁的竞争和提高并发性能。
  2. synchronized可以用于静态方法和实例方法,对于静态方法,锁定的是类的Class对象,对于实例方法,锁定的是实例对象。
  3. synchronized可以用于代码块,通过synchronized(锁对象)的方式指定锁对象,锁对象可以是任意Java对象,但是需要保证所有线程都使用同一个锁对象。
  4. 在使用synchronized时,应该尽量减小锁的粒度,即只在必要的代码块中使用synchronized,以避免出现死锁、饥饿等问题。

综上所述,synchronized是Java中用于保护共享资源的内置锁,具有可重入性、可见性、原子性等特点。在使用synchronized时需要注意锁的粒度和锁的竞争问题,以保证多线程环境下的数据一致性和正确性。

例子

下面是一个使用synchronized的例子,用于保护共享资源的并发访问:

public class Counter {
    private int count;

    public synchronized void increment() {
        count++;
    }

    public synchronized void decrement() {
        count--;
    }

    public synchronized int getCount() {
        return count;
    }
}

在这个例子中,Counter类有一个共享的count变量,increment()方法和decrement()方法分别对count变量进行加1和减1操作,getCount()方法返回count变量的当前值。由于count变量是共享资源,在多线程环境下可能会出现数据竞争和一致性问题,因此需要使用synchronized关键字来保护它的并发访问。

在这个例子中,increment()、decrement()和getCount()方法都使用了synchronized关键字,这样同一时刻只有一个线程能够访问这些方法,其他线程必须等待锁的释放才能访问这些方法,从而保证了count变量的并发访问的线程安全性和正确性。

需要注意的是,在这个例子中,使用了synchronized关键字修饰整个方法,这样虽然可以保证方法的线程安全性,但是也会造成锁的竞争和性能下降。如果只需要保护部分代码块的并发访问,可以使用synchronized代码块的方式,以减小锁的粒度和提高并发性能。

上次编辑于:
贡献者: Neil