synchronized 可以根据不同的id加锁吗

天天向上zhougf 发布于 09/18 14:56
阅读 283
收藏 1

   @Override
    public synchronized Integer insert(Integer id) {
            System.out.println(id);
            int count = repeatDao.countById("zhou");
            if (count < 30) {
                return repeatDao.add(id);
            }
            return  1;
    }

求大佬接答 这个地方我不想锁整个方法 会影响效率 我可以根据不同的id加锁吗 即该id的用户进来是否等待与其他id 没有关系

加载中
0
kakai
kakai

不可以,除非你预先将所有id进行 String.intern() 操作后放入String常量池, synchronized 锁住的对象必须是内存地址固化的对象,一旦可变,锁无效。

kakai
kakai
回复 @天天向上zhougf : 2楼的代码可以参考一下,再就是数据库行级锁了。
天天向上zhougf
天天向上zhougf
回复 @kakai : 是的 我回调逻辑内 会改数据库的一个状态 我是根据这个状态判断是否已经处理过 但它是多线程的我第一次还没处理完 第二次已经进来了 导致有些拦截不住
kakai
kakai
回复 @天天向上zhougf : 加锁无法避免某个用户重复回调,除非你加锁的方法中判断了一个标识已经回调的参数,不然加锁仅仅是把后续的回调延后执行而已,这样的话,整个系统资源将会被严重浪费。如果你是单台服务,且每个回调行为都有办法唯一标识,可以用这个唯一标识判断是否已回调,多机器的话可以使用redis等。
天天向上zhougf
天天向上zhougf
回复 @kakai : 大佬 我这个场景是项目上 我用户登录xxxxxx调别的接口 然后接口会多线程的重复回调我 我想判断是否接收到过回调 避免重复回调 所以锁了整个方法 但这样会影响其他用户调这个接口的效率 所以想针对不同的用户加锁 有什么好的方案吗 多谢
kakai
kakai
回复 @天天向上zhougf : :blush:
下一页
0
小小行者
小小行者

其实这个可以通过异步操作的方式来解决,我给你一个简单的处理方式,你加一张表回调表,所有来调你接口的参数,你接收后,存进这张表,接收的接口不做任何处理。有另一个程序定时扫这张表,这种再判断是否重复调过的压力就不大了。因为是你自己找的,不存在大量行为。重复的或者做过的都从这张表移除,这种类似mq的处理方式。当然还有多种方式解决你的问题,你可以自己多想想。

kakai
kakai
回复 @天天向上zhougf : 并发多的话严重增加数据库的写入压力,并发少还不如你目前这种在方法上加锁或者数据库行级锁。不建议使用此种方式。
天天向上zhougf
天天向上zhougf
好的 谢谢 这属于换种思路解决了
0
开源中国-不入流码农
开源中国-不入流码农

你想搞事情哦,不同用户等待不同时间哦

返回顶部
顶部