欢迎访问宙启技术站
智能推送

Java多线程编程中常用的synchronized函数及应用实践

发布时间:2023-06-23 08:08:13

Java多线程编程中,synchronized是一种控制并发的基本机制。该机制可以将多个线程对同一个资源的竞争控制在同步范围内,保证同一时刻只有一个线程能够访问该资源,从而避免了多个线程同时访问同一个资源而产生的问题,如数据错误、死锁等。

synchronized函数是一种在方法上直接声明同步的方式。在Java中,synchronized函数可以用来同步方法,以达到保护共享资源的目的。其简单的语法如下:

public synchronized void functionName(){  
    //方法体  
}

synchronized函数的应用实践主要包括以下几个方面:

1.同步成员方法

在Java中,每个对象都有一个锁。如果多个线程同时访问同一个对象的同步代码块或同步函数时,只有其中一个线程能够获取该对象的锁,并执行相应的代码。其余线程则会进入阻塞状态,等待锁释放后再继续执行。因此,同步函数可以被用来保护共享资源,以避免多个线程同时访问而引发的问题。

例如,我们可以创建一个账户类,并在其中定义存款和取款的方法。由于账户的余额是共享资源,因此我们需要使用synchronized函数来保护它。

public class Account {
    private double balance;
    // 存款
    public synchronized void deposit(double amount) {
        balance += amount;
    }
    // 取款
    public synchronized void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
        }
    }
}

在上述代码中,deposit()和withdraw()方法都被声明为同步方法。这样,当多个线程同时调用这些方法时,只有一个线程可以访问这些方法,并获取账户对象的锁。其他线程则会被阻塞,直到锁被释放后才能继续执行。

2.锁定对象

在Java中,synchronized关键字可以应用于代码块、方法和对象上。对于同步代码块和同步方法,其锁定对象都是调用该方法或执行该代码块的对象。而对于同步对象,其锁定的是一个指定的对象。

例如,我们可以在代码块和方法中使用同一个对象来锁定一段代码:

public class PrintThread extends Thread {
    private static Object lock = new Object();
    public void run() {
        synchronized(lock) {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
    public synchronized void print() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}

在上述代码中,我们先定义了一个静态对象lock,并在run方法中通过synchronized(lock)来锁定一段代码。同时,我们还定义了一个print方法,并在其中使用synchronized关键字来实现同步。这里值得注意的是,当使用synchronized关键字来锁定一段代码时,一定要保证锁定对象是共享的,否则就会失去同步的作用。

3.锁定类

在Java中,synchronized函数还可以被用来锁定一个类。锁定类可以防止多个线程同时执行该类的静态同步方法,从而达到保护共享资源的目的。

例如,我们可以创建一个计数器类,并在其中定义一个静态的同步函数。

public class Counter {
    private static int count;
    public static synchronized void increment() {
        count++;
    }
}

在上述代码中,我们通过synchronized关键字来声明increment方法是一个静态同步函数,并用来锁定Counter类。这样,当多个线程同时调用increment方法时,只有一个线程可以获取Counter类的锁,从而保证只有一个线程可以执行该方法。

总之,synchronized函数在Java多线程编程中是一种非常重要的机制,它可以用来保护共享资源,防止多个线程同时访问而引发的问题。在实践中,我们需要根据具体的需求来选择不同的同步方式,从而达到 的效果。