📜  门| GATE-CS-2017(套装2)|第 36 题(1)

📅  最后修改于: 2023-12-03 15:28:45.656000             🧑  作者: Mango

题目

门| GATE-CS-2017(套装2)|第 36 题

问题描述

一个线程安全的计数器对象需要支持下列两个操作:

  • inc()-将计数器的值加1并返回计数器的值
  • get()-返回计数器的值

考虑在实现这个计数器对象的时候,有多个线程调用 inc()get() 操作。下列哪种情况是正确的?

A. 计数器对象由一个 synchronized 方法 incAndGet() 实现,方法中对计数器变量调用 wait()notifyAll(),并获得或释放 synchronized 锁。

B. 计数器对象由一个 synchronized 方法 incAndGet() 实现,方法中调用 wait()notifyAll(),并获得或释放 synchronized 锁。

C. 计数器对象由一个 ReentrantLock 对象保护,所有的访问都必须先获取该锁,其中 incAndGet()get() 方法都是 synchronized 类型。

D. 计数器对象由一个 ReentrantLock 对象保护,所有的访问都必须先获取该锁,其中 inc()get() 方法都是 synchronized 类型。

解题思路

在多线程并发操作下,确保计数器的值正确性需要使用线程安全的方式。其中一种方式是使用同步方法或同步块,确保同一时间只有一个线程对计数器进行操作。

在本题中,A 选项中使用 wait()notifyAll() 来协调多个线程的访问,但是没有正确的 synchronized 锁来进行同步操作,因此 A 选项是错误的。

B 选项中使用了 synchronized 锁,但是没有使用同步方法或同步块来进行同步操作,而是直接调用了 wait()notifyAll() 来协调访问,因此 B 选项也是错误的。

C 选项使用了 ReentrantLock 锁来保护计数器,需要先获取锁才能访问计数器。其中 incAndGet()get() 方法都是 synchronized 类型的,但是使用 ReentrantLock 来保护计数器其实已经足够了,不需要再使用同步方法或同步块来进行同步操作,因此 C 选项是正确的。

D 选项使用了 ReentrantLock 锁来保护计数器,需要先获取锁才能访问计数器,但是 inc()get() 方法都是 synchronized 类型的,这是多余的,因为已经通过 ReentrantLock 锁来保证了同步访问,因此 D 选项也是错误的。

因此,正确答案是 C。

答案

正确答案:C

参考资料
  1. 《Java并发编程实战》
  2. 《深入理解Java虚拟机》