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 是非常必要的。
显示 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 域会立即写入到主存中,而且读操作也发生在主存中。
- sychronized 和 volatile 不可以同时使用。当多个任务同时访问一个域时,那么它应该是 volatile 的,否则这个域只能由同步来访问。同步会导致主存刷新,如果一个域由 sychronized 防护,那就不需要设置 volatile 了。