java - HashMap 通过 2 种不同的方法进行操作 - 多线程和并发

标签 java multithreading performance synchronization synchronized

我有以下代码片段,包含 2 个不同的方法,这两个方法将被许多线程访问(getWeapon() 和 returnWeapon())。

请任何能够回答以下部分或全部问题的人: 1. 如何使其尽可能高效? 2.我可以不使用synchronized block 吗? 3. 使用不同的对象作为synchronizd block 的键是否更好? 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.concurrent 功能通常和 Reentrant/ReadWriteLock 特别使用非阻塞方法,然后可能会更快 - 但是否完全取决于线程如何与共享数据交互......

  • 关于java - HashMap 通过 2 种不同的方法进行操作 - 多线程和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49431426/

    相关文章:

    java - 使 spring @Value 从静态字段中获取默认值

    java - :mobile:compileDebugJavaWithJavac FAILED

    iphone - 如何在 iPhone 上访问 safari、facebook 等应用程序的远程连接请求

    mysql - 如何快速将非常大的 csv 文件导入 mysql?

    c++ - Armadillo inplace_plus 明显慢于 "normal"plus 操作

    java - 如何传递或分配在 runOnUiThread 中获得的值

    c# - 当创建后台工作人员的进程完成时,后台工作人员是否停止

    C# 将较大的方法分成两个线程

    python - numpy数组比较的高效Python实现

    java - Double != null 导致 NullPointerException