Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Wismyluckstar opened this issue May 25, 2020 · 5 comments

Comments

@Wismyluckstar
Copy link

image

@lkqm
Copy link

lkqm commented May 31, 2020

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

@binarywang
Copy link
Member

已修复

@cookier
Copy link

cookier commented Sep 16, 2020

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

@lkqm
Copy link

lkqm commented Sep 16, 2020

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

@cookier
Copy link

cookier commented Sep 17, 2020

在做测试之前,看你的说明后我理解是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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants