用ConcurrentHashMap+锁 优化synchronized方法

1、问题发现

虽说,synchronized 关键字万能的,在并发上去之后,这个插入就显得很慢了。仔细观察发现,其实锁的粒度还是再细点,可以根据AlarmRules对象的ID来锁。

2、解决过程

很明显synchronized(rules) 这个写法是有问题的。是基于对象的引用作为锁,只有在rules实例相同的情况下。我们实际情况实例不同,id相同的情况。

查询相关资料。进行相关测试 采用

ConcurrentHashMap(线程安全map) + ​ReentrantLock(可重入的锁)

public class MainTest {

    public static void main(String[] args) {
        for (int i = 1; i < 20; i++) {
            AlarmRules temp = new AlarmRules();
            temp.setId(i % 4);

            new Thread(new Test(temp)).start();
        }
        System.out.println("for end");
    }
}


​Runnable

public class Test implements Runnable {

    private AlarmRules bean;

    public Test(AlarmRules bean){
        this.bean = bean;
    }

    @Override
    public void run() {
        SynchTest.synchMethod(bean);
    }
}

method

public class SynchTest {


    private static final Map<Integer, ReentrantLock> LOCK_MAP = new ConcurrentHashMap<>();

    public static void synchMethod(AlarmRules bean){
        ReentrantLock lock = LOCK_MAP.computeIfAbsent(bean.getId(), k -> new ReentrantLock());
        lock.lock();
        try {
            System.out.println("bean.getId() = " + bean.getId()+" bean selectOne");
            Thread.sleep(2000);
            System.out.println("bean.getId() = " + bean.getId()+" bean insert");

            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }


    }
}

效果实现。id不同的完美并发执行。提高了方法的效率。

注意

因我有用 CountDownLatch,在latch.await();  清理资源

LOCK_MAP.remove(rules.getId()); 避免OOM

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值