>我有以下代码片段,包含 2 个不同的方法,这两种方法都可以被许多线程访问(getWeapon(( 和 returnWeapon(((。
请任何可以回答以下部分或全部问题的人:1. 如何使其尽可能高效?2. 我不能使用同步块吗?3. 使用不同的对象作为同步块的键更好吗?4. 使用ReentrantLock/ReadWriteLock来处理这种狡猾的多线程情况是否更好?
private static final int M16_NUM_WEAPONS = 2;
private static final int AK47_NUM_WEAPONS = 5;
private static final int UZI_NUM_WEAPONS = 9;
private Map<Class<? extends Weapon>, Integer> WeaponsToAmountMap;
public Arsenal() {
this.synchronizedWeaponsToAmountMap = new ConcurrentHashMap<Class<? extends Weapon>, Integer>();
}
public void initializeWeapons() {
synchronizedWeaponsToAmountMap.put(M16.class, M16_NUM_WEAPONS);
synchronizedWeaponsToAmountMap.put(AK47.class, AK47_NUM_WEAPONS);
synchronizedWeaponsToAmountMap.put(Uzi.class, UZI_NUM_WEAPONS);
}
public Weapon getWeapon(Fighter fighter) {
List<Class<? extends Weapon>> allowedWeapons = new ArrayList<>(fighter.getAllowedWeapons());
Class<? extends Weapon> weaponClass = null;
for (Class<? extends Weapon> allowedWeapon : allowedWeapons){
synchronized (this) {
Integer amount = synchronizedWeaponsToAmountMap.get(allowedWeapon);
if (amount != null && amount > 0) {
synchronizedWeaponsToAmountMap.put(allowedWeapon, amount - 1);
System.out.println("Taking : "+allowedWeapon.getSimpleName());
weaponClass = allowedWeapon;
break;
}
}
}
if (weaponClass==null){
return null;
}
Weapon weapon = null;
try {
weapon = weaponClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return weapon;
}
public void returnWeapon(Weapon weapon) {
if (weapon==null){
return;
}
synchronized(this) {
System.out.println("returning : "+weapon.getClass().getSimpleName());
synchronizedWeaponsToAmountMap.put(weapon.getClass(), synchronizedWeaponsToAmountMap.get(weapon.getClass()) + 1);
}
}
-
我认为同步是在一个或多个或不同的监视器对象上完成的,这并没有太大的不同:一旦您想防止不同的线程同时访问相同的共享数据,您就可以使用同步,它将访问线性化,然后增加时间。
-
java.util.并发功能通常和Reentrant/ReadWriteLock特别使用非阻塞方法,然后可能会更快 - 但是否完全取决于您的线程如何与共享数据交互...