HashMap 在 2 种不同的方法上操作 - 多线程和 cuncurrency



>我有以下代码片段,包含 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);
    }
}
  1. 我认为同步是在一个或多个或不同的监视器对象上完成的,这并没有太大的不同:一旦您想防止不同的线程同时访问相同的共享数据,您就可以使用同步,它将访问线性化,然后增加时间。

  2. java.util.并发功能通常和Reentrant/ReadWriteLock特别使用非阻塞方法,然后可能会更快 - 但是否完全取决于您的线程如何与共享数据交互...

最新更新