返回

Java并发编程 - synchronized 的魅力之旅

Android

引言

各位开发者,欢迎踏上 Java 并发编程之旅的第 53 站。今天,我们将深入探讨 synchronized ,它的魅力在于确保并发环境中的代码执行安全。让我们一起揭开它的奥秘!

目录

  • synchronized 的使用方式
  • synchronized 的原理
  • 线程的等待、中断与唤醒

一、synchronized 的使用方式

synchronized 可以保证在同一个时刻,只有一个线程执行被 synchronized 修饰的代码块或方法。有以下几种使用方式:

1. 修饰方法

public synchronized void someMethod() {
    // ...
}

2. 修饰代码块

synchronized (this) {
    // ...
}

其中,this 表示当前对象。

二、synchronized 的原理

synchronized 的实现依赖于 Java 对象头中的一个 监视器锁 。当一个线程获取某个对象的监视器锁时,它就获得了该对象的独占访问权,其他线程将被阻塞,直到该锁被释放。

三、线程的等待、中断与唤醒

1. 线程等待

使用 wait() 方法可以使线程进入等待状态,直到监视器锁被释放。

synchronized (this) {
    this.wait();
}

2. 线程中断

可以使用 interrupt() 方法中断处于等待状态的线程。

synchronized (this) {
    this.wait();
    // 如果被中断,执行后续操作
}

3. 线程唤醒

通过 notify()notifyAll() 方法,持有监视器锁的线程可以唤醒一个或所有等待的线程。

synchronized (this) {
    this.notify();
}

收获

  • 理解 synchronized 的使用方式和原理。
  • 掌握线程的等待、中断与唤醒机制。

案例研究

让我们编写一个简单的多线程程序,演示 synchronized 的用法:

public class Counter {
    private int count;

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

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();

        Thread[] threads = new Thread[100];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    counter.increment();
                }
            });
        }

        for (Thread thread : threads) {
            thread.start();
        }

        for (Thread thread : threads) {
            thread.join();
        }

        System.out.println("Final count: " + counter.count);
    }
}

在这个程序中,我们创建了一个 Counter 类,它的 increment() 方法使用 synchronized 关键字进行保护,确保每次只有一个线程可以增加 count 变量。我们创建了 100 个线程,每个线程都执行 1000 次 increment() 操作。通过使用 synchronized,我们保证了 count 变量在并发环境下可以被安全地更新。

总结

Java 的 synchronized 关键字为并发编程提供了强大的保障机制,帮助我们编写出安全可靠的多线程程序。通过理解它的使用方式、原理和线程同步机制,开发者可以充分发挥并发编程的优势,创建出高效且无并发问题的应用程序。