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

Java函数如何实现多线程的同步和互斥操作?

发布时间:2023-06-15 00:11:24

在 Java 中,多线程并发操作经常会产生线程安全问题,如数据竞争、死锁等。为了解决这些问题,Java 提供了以下几种机制实现多线程的同步和互斥操作。

1. Synchronized 关键字

synchronized 关键字可以修饰方法和代码块。当线程执行到 synchronized 修饰的代码块或方法时,会尝试获得锁。如果锁已经被其他线程持有,则该线程会进入阻塞状态,直到其他线程释放锁。这样就可以保证了同一时刻只有一个线程访问该方法或代码块,避免了数据竞争和死锁。

例子:

public synchronized void syncMethod(){
    //…
}

public void syncBlock(){
    synchronized(this){
        //…
    }
}

2. ReentrantLock 类

ReentrantLock 类是一个可重入锁,它提供了更灵活的锁机制,支持公平锁和非公平锁。在使用 ReentrantLock 时,需要手动获取锁和释放锁,并且需要在 finally 块中释放锁,避免死锁。

例子:

private final ReentrantLock lock = new ReentrantLock();

public void syncMethod(){
    lock.lock();
    try {
        //…
    } finally {
        lock.unlock();
    }
}

3. Wait、Notify 和 NotifyAll 方法

在使用 synchronized 或 ReentrantLock 锁时,可以通过 Wait、Notify 和 NotifyAll 方法来实现线程的等待和唤醒。Wait 方法会使当前线程进入阻塞状态,等待其他线程通过 Notify 或 NotifyAll 方法来唤醒它。Notify 方法会唤醒一个被阻塞的线程,而 NotifyAll 方法会唤醒所有被阻塞的线程。

例子:

public class WaitNotifyTest {

    public static void main(String[] args) {
        Object lock = new Object();
        Thread t1 = new Thread(new Waiter(lock));
        Thread t2 = new Thread(new Waiter(lock));
        Thread t3 = new Thread(new Notifier(lock));
        t1.start();
        t2.start();
        t3.start();
    }

    static class Waiter implements Runnable {
        private Object lock;

        public Waiter(Object lock) {
            this.lock = lock;
        }

        public void run() {
            synchronized (lock) {
                try {
                    lock.wait();
                    System.out.println(Thread.currentThread().getName() + " is notified.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class Notifier implements Runnable {
        private Object lock;

        public Notifier(Object lock) {
            this.lock = lock;
        }

        public void run() {
            synchronized (lock) {
                lock.notifyAll();
                System.out.println(Thread.currentThread().getName() + " notifies all.");
            }
        }
    }
}

4. Atomic 类

Atomic 类是 Java 提供的一组原子操作类,用于实现线程安全的变量自增、自减、赋值等操作。它通过底层的 CAS(Compare And Swap)机制来保证原子性。

例子:

private AtomicInteger counter = new AtomicInteger(0);

public void increment() {
    counter.incrementAndGet();
}

总结

Java 通过以上几种机制来实现多线程的同步和互斥操作,可以根据具体的场景选择合适的方法。在使用这些机制时,需要注意线程安全问题,避免数据竞争、死锁等问题的发生。