Skip to content

获取accessToken先加锁,会导致后续的请求需要很长时间才能拿到锁 #1582

Closed

Description

@Wismyluckstar

image

Activity

  1. lkqm commented on May 31, 2020

    @lkqm

    目前确实会存在这样的问题, 后续使用lock.tryLock修复这个问题

  2. added a commit that references this issue on May 31, 2020
    829b103
  3. added a commit that references this issue on May 31, 2020
  4. binarywang commented on Jul 19, 2020

    @binarywang
    Owner

    已修复

  5. cookier commented on Sep 16, 2020

    @cookier

    请问一下把lock改成tryLock有什么提升吗?
    因为我看这里tryLock也是通过不断循环,判断是否锁住,跟lock直接锁住好像效果一样?

  6. lkqm commented on Sep 16, 2020

    @lkqm

    如果用lock这里有上万个请求会导致最后一个请求会等待前面9999个人的时间。而实际上只希望请求tencent获取accessToen只有一个线程,而使用tryLock会在某个线程更新accessToken后,其余线程只需要短暂等待后即可获取有效的accessToekn.

  7. cookier commented on Sep 17, 2020

    @cookier

    在做测试之前,看你的说明后我理解是lock为单纯阻塞,并发线程都在干等着;tryLock则保持了并发线程的灵活性,只需要短暂等待就能拿到结果。不过再仔细想,每个线程都要额外等多100毫秒,响应不是更慢吗?
    模拟并发测试后发现lock方式执行时间1000+。tryLock执行时间3000+,不知道我测试方式是否正确。

        private Lock lock = new ReentrantLock();
        static boolean flag = false;
        static long x = System.currentTimeMillis();
    
        @Test
        public void testLock() throws IOException {
            for (int i = 0; i < 1000; i++) {
                new Thread(() -> doSome()).start();
            }
            System.in.read();
        }
    
        public void doSome() {
            lock.lock();
            try {
                if (flag) {
                    return;
                }
                System.out.println(Thread.currentThread().getName() + "得到了锁" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss:SSS"));
                //模拟耗时操作
                Thread.sleep(1000);
                flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                System.out.println(System.currentTimeMillis() - x);
            }
        }
    
        public void doSome2() {
            boolean locked = false;
            try {
                do {
                    locked = lock.tryLock(100,TimeUnit.MICROSECONDS);
                    if (flag) {
                        return;
                    }
                } while (!locked);
    
                System.out.println(Thread.currentThread().getName() + "得到了锁" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss:SSS"));
                //模拟耗时操作
                Thread.sleep(1000);
                flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (locked) {
                    lock.unlock();
                }
                System.out.println(System.currentTimeMillis() - x);
            }
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions