Java 中 Synchronized 关键字的作用

简介

Synchronized 关键字是 Java 中一种用于实现线程同步的机制。在多线程程序中,当多个线程同时访问共享资源时,可能会导致数据的不一致性和程序的错误行为。Synchronized 关键字可以解决这个问题,使得多个线程在访问共享资源时能够按照一定的顺序执行,从而保证程序的正确性。
在这里插入图片描述

作用

Synchronized 关键字可以用于两种情况:方法和代码块。在方法上使用 Synchronized 关键字可以保证方法的原子性,即在同一时刻只有一个线程可以执行该方法。在代码块上使用 Synchronized 关键字可以保证代码块的原子性,并且可以指定同步对象,即同步锁,来控制多个线程的访问顺序。

下面通过一个代码示例来说明 Synchronized 关键字的用法。

public class SynchronizedExample implements Runnable {
    private int count = 0;

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

    public void run() {
        for (int i = 0; i < 10000; i++) {
            increment();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedExample synchronizedExample = new SynchronizedExample();
        Thread t1 = new Thread(synchronizedExample);
        Thread t2 = new Thread(synchronizedExample);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(synchronizedExample.count);
    }
}

在这个示例中,我们定义了一个 SynchronizedExample 类,该类实现了 Runnable 接口。在 SynchronizedExample 类中,我们定义了一个私有属性 count 和一个公共方法 increment()。increment() 方法使用 synchronized 关键字修饰,以保证在同一时刻只有一个线程可以执行该方法。在 run() 方法中,我们循环调用 increment() 方法 10000 次来增加 count 的值。在 main() 方法中,我们创建了两个线程 t1 和 t2,并将它们都指向同一个 SynchronizedExample 实例。然后,我们启动这两个线程并等待它们的执行完成,最后输出 count 的值。

通过这个示例,我们可以看到 Synchronized 关键字的作用:保证了 increment() 方法的原子性,即在同一时刻只有一个线程可以执行该方法,从而保证了 count 的值的正确性。

除了在方法上使用 Synchronized 关键字外,我们还可以在代码块上使用 Synchronized 关键字来控制多个线程的访问顺序。在代码块上使用 Synchronized 关键字时,需要指定同步对象,即同步锁。同步锁可以是任意对象,但是需要保证多个线程使用的同步锁是同一个对象。下面是一个示例代码:

public class SynchronizedExample2 implements Runnable {
    private final Object lock = new Object();
    private int count = 0;

    public void run() {
        synchronized (lock) {
            for (int i = 0; i < 10000; i++) {
                count++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedExample2 synchronizedExample2 = new SynchronizedExample2();
        Thread t1 = new Thread(synchronizedExample2);
        Thread t2 = new Thread(synchronizedExample2);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(synchronizedExample2.count);
    }
}

在这个示例中,我们定义了一个 SynchronizedExample2 类,该类实现了 Runnable 接口。在 SynchronizedExample2 类中,我们定义了一个私有属性 lock 和一个公共方法 run()。在 run() 方法中,我们使用 synchronized 关键字修饰了一个代码块,并指定了同步锁为 lock。在代码块中,我们循环增加 count 的值。在 main() 方法中,我们创建了两个线程 t1 和 t2,并将它们都指向同一个 SynchronizedExample2 实例。然后,我们启动这两个线程并等待它们的执行完成,最后输出 count 的值。

通过这个示例,我们可以看到 Synchronized 关键字在代码块上的作用:使用同步锁来控制多个线程的访问顺序,从而保证 count 的值的正确性。

除了在 Java 中使用 Synchronized 关键字,还可以使用其他的线程同步机制,例如 Lock 和 Semaphore。Lock 是一个接口,提供了比 Synchronized 更灵活的线程同步机制,可以实现公平锁和非公平锁。Semaphore 是一个计数信号量,可以用来控制访问某个共享资源的线程数。

然而,在实际开发中,Synchronized 关键字仍然是最常用的线程同步机制之一。因为它简单易用,且可以自动释放锁,避免了死锁的发生。同时,Synchronized 关键字也是 JVM 内部实现的一种机制,具有较高的性能和可靠性。

在实际开发中,我们应该尽量减少对共享资源的访问,从而减少线程同步的需求。如果必须使用共享资源,应该尽量保证共享资源的不可变性,即共享资源的值不会被修改。另外,我们还可以使用线程安全的集合类,例如 ConcurrentHashMap 和 CopyOnWriteArrayList,来减少线程同步的需求。

总结

总之,Synchronized 关键字是 Java 中一种用于实现线程同步的机制。它可以保证方法和代码块的原子性,并且可以控制多个线程的访问顺序,从而保证程序的正确性。在实际开发中,我们应该尽量减少对共享资源的访问,并使用线程安全的集合类来减少线程同步的需求。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
synchronized 关键字Java 的一个关键字,用于实现并发编程的同步。它可以用于方法、代码块和静态方法上。 1. 用法一:修饰实例方法 当一个线程访问一个对象的 synchronized 实例方法时,其他线程不能访问该对象的其他 synchronized 实例方法,但可以访问该对象的非 synchronized 实例方法。这种方式的锁是当前实例对象。 示例代码: ```java public synchronized void syncMethod() { // synchronized 代码块 } ``` 2. 用法二:修饰代码块 synchronized 代码块可以用来同步访问共享资源,它必须接收一个对象作为参数,该对象被称为锁对象。当线程进入 synchronized 代码块时,它必须获得锁对象的锁,其他线程在此时无法获得锁对象的锁,只有等待锁被释放。 示例代码: ```java public void syncBlock() { synchronized(this) { // synchronized 代码块 } } ``` 3. 用法三:修饰静态方法 当一个线程访问一个类的 synchronized 静态方法时,其他线程不能访问该类的其他 synchronized 静态方法,但可以访问该类的非 synchronized 静态方法。这种方式的锁是当前类的 Class 对象。 示例代码: ```java public static synchronized void syncStaticMethod() { // synchronized 代码块 } ``` 需要注意的是,使用 synchronized 关键字会降低程序的性能,因为当一个线程获得锁时,其他线程必须等待该线程释放锁才能继续执行,这会增加线程的上下文切换和调度开销。因此,在进行并发编程时,应该尽量避免使用 synchronized 关键字,而是使用更高级别的同步机制,如 Lock、Semaphore、CountDownLatch 等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT徐师兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值