java 同步访问不同的临界区
java synchronizing access to different critical sections
我有一个如下所示的方法。
public class CriticalSections
{
public void mainMethod(boolean b)
{
if (b) {
method1();
}
else {
criticalMethod();
method2();
}
}
private void criticalMethod()
{
System.out.println("in criticalMethod");
}
private void method1()
{
System.out.println("in method1");
}
private void method2()
{
System.out.println("in method2");
}
}
我需要限制对这些方法的访问,这样
- 当线程访问 criticalMethod() 时,对于所有其他 threads.Similarly 线程访问 method1() 和 method2() 时,应限制对 method1() 和 method2() 的访问,应限制所有其他线程访问 criticalMethod()。
- method1() 可以被不同线程单独并发访问。
- method2() 可以被不同的线程单独并发访问。
- method1() 和 method2() 可以被不同的线程同时访问。
为了满足第一个访问条件我想出了下面的代码,
但这不会满足其他 3 个条件,因此性能会受到影响。
public class CriticalSections
{
private final Lock lock1 = new ReentrantLock();
private final Lock lock2 = new ReentrantLock();
private final Lock lock3 = new ReentrantLock();
public void mainMethod(boolean b)
{
if (b) {
lock1.tryLock();
try {
method1();
}
finally {
lock1.unlock();
}
}
else {
lock1.tryLock();
try {
lock2.tryLock();
try {
lock3.tryLock();
try {
criticalMethod();
}
finally {
lock3.unlock();
}
}
finally {
lock2.unlock();
}
}
finally {
lock1.unlock();
}
}
lock3.tryLock();
try {
method2();
}
finally {
lock3.unlock();
}
}
private void criticalMethod()
{
System.out.println("in criticalMethod");
}
private void method1()
{
System.out.println("in method1");
}
private void method2()
{
System.out.println("in method2");
}
}
应该使用什么同步机制来满足上述场景?
您需要的是对 criticalMethod
的独占锁和对方法 method1
和 method2
的共享锁。实现此目的的最简单方法是使用 java.util.concurrent.locks.ReentrantReadWriteLock
,如下所示:
public class CriticalSections {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void mainMethod(boolean b) {
if (b) {
method1();
} else {
criticalMethod();
method2();
}
}
private void criticalMethod() {
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
System.out.println("in criticalMethod");
} finally {
writeLock.unlock();
}
}
private void method1() {
Lock readLock = lock.readLock();
readLock.lock();
try {
System.out.println("in method1");
} finally {
readLock.unlock();
}
}
private void method2() {
Lock readLock = lock.readLock();
readLock.lock();
try {
System.out.println("in method2");
} finally {
readLock.unlock();
}
}
}
如果你担心性能,你也可以take a look at java.util.concurrent.locks.StampedLock
(Java 8+).
我有一个如下所示的方法。
public class CriticalSections
{
public void mainMethod(boolean b)
{
if (b) {
method1();
}
else {
criticalMethod();
method2();
}
}
private void criticalMethod()
{
System.out.println("in criticalMethod");
}
private void method1()
{
System.out.println("in method1");
}
private void method2()
{
System.out.println("in method2");
}
}
我需要限制对这些方法的访问,这样
- 当线程访问 criticalMethod() 时,对于所有其他 threads.Similarly 线程访问 method1() 和 method2() 时,应限制对 method1() 和 method2() 的访问,应限制所有其他线程访问 criticalMethod()。
- method1() 可以被不同线程单独并发访问。
- method2() 可以被不同的线程单独并发访问。
- method1() 和 method2() 可以被不同的线程同时访问。
为了满足第一个访问条件我想出了下面的代码, 但这不会满足其他 3 个条件,因此性能会受到影响。
public class CriticalSections
{
private final Lock lock1 = new ReentrantLock();
private final Lock lock2 = new ReentrantLock();
private final Lock lock3 = new ReentrantLock();
public void mainMethod(boolean b)
{
if (b) {
lock1.tryLock();
try {
method1();
}
finally {
lock1.unlock();
}
}
else {
lock1.tryLock();
try {
lock2.tryLock();
try {
lock3.tryLock();
try {
criticalMethod();
}
finally {
lock3.unlock();
}
}
finally {
lock2.unlock();
}
}
finally {
lock1.unlock();
}
}
lock3.tryLock();
try {
method2();
}
finally {
lock3.unlock();
}
}
private void criticalMethod()
{
System.out.println("in criticalMethod");
}
private void method1()
{
System.out.println("in method1");
}
private void method2()
{
System.out.println("in method2");
}
}
应该使用什么同步机制来满足上述场景?
您需要的是对 criticalMethod
的独占锁和对方法 method1
和 method2
的共享锁。实现此目的的最简单方法是使用 java.util.concurrent.locks.ReentrantReadWriteLock
,如下所示:
public class CriticalSections {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void mainMethod(boolean b) {
if (b) {
method1();
} else {
criticalMethod();
method2();
}
}
private void criticalMethod() {
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
System.out.println("in criticalMethod");
} finally {
writeLock.unlock();
}
}
private void method1() {
Lock readLock = lock.readLock();
readLock.lock();
try {
System.out.println("in method1");
} finally {
readLock.unlock();
}
}
private void method2() {
Lock readLock = lock.readLock();
readLock.lock();
try {
System.out.println("in method2");
} finally {
readLock.unlock();
}
}
}
如果你担心性能,你也可以take a look at java.util.concurrent.locks.StampedLock
(Java 8+).