Java 并发资源竞争

127 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

  • 逛牛客的时候经常会看到有关于 Java 并发相关的面试问题,所以打算对 Java 并发内容进行整理总结。这是第二篇,包括 sychronized、volatile 关键字和 lock 对象。

synchronized 关键字

  • sychronized 是 Java 内置的关键字。它是在执行任务的时候用来保护代码片段的 (①检查锁是否可用 --> ②获取锁 --> ③执行代码 --> ④释放锁)。
public obj extends IntGenerator {
    private int currentEventValue = 0;
    pbulic obj() {}
    public sychronized int next() {
        currentEventValue++;
        Thread.yield();
        currentEventValue++;
        return currentEventValue;
    }
}
  • 共享资源一般是以对象的形式存在的,要控制对共享资源的访问就先要将共享对象包装成为对象。最后将访问该资源的方法标记为 sychronized
  • 对于同一个对象,它的所有 sychronized 方法将会共享一个锁,以防止多任务同时访问时被编码为对象内存。
  • 在并发使用时,sychronized 关键字不能够防止其他任务直接访问域,所以我们将域设置为 private 是非常必要的。

1.jpeg

显示 Lock 对象

  • Lock 对象需要显示地创建、锁定和释放。
public obj extends IntGenerator {
    private int currentEventValue = 0;
    pbulic obj() {}
    private Lock lock = new ReentrankLock();
    public int next() {
        lock.lock();
        try {
            currentEventValue++;
            Thread.yield();
            currentEventValue++;
            return currentEventValue;
        } finally {
            lock.unlock();
        }
    }
}
  • 对比 sychronized 关键字。在使用 sychronized 关键字时,如果事务失败就会抛出一个异常,并没有处理异常让系统恢复良好状态;使用 Lock 对象之后。就可以在 finally 子句中维护系统地正常状态。

volatile 关键字

  • volatile 保证了应用中地可视性。如果将一个域设置为 volatile 的,只要对这个域产生了写的操作,那么所有读的操作都将会看到这个修改。在实际情况中 volatile 域会立即写入到主存中,而且读操作也发生在主存中。

2.jpeg

  • sychronizedvolatile 不可以同时使用。当多个任务同时访问一个域时,那么它应该是 volatile 的,否则这个域只能由同步来访问。同步会导致主存刷新,如果一个域由 sychronized 防护,那就不需要设置 volatile 了。