首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弹簧引导: ReentrantLock

弹簧引导: ReentrantLock
EN

Stack Overflow用户
提问于 2020-03-10 11:18:09
回答 1查看 1.5K关注 0票数 0

我编写了一个@Repository类:

代码语言:javascript
复制
@Repository
public class RepositoryDocumentDao {

    private static final Logger LOG = LoggerFactory.getLogger(RepositoryDocumentDao.class);
    private ReentrantLock lock;

    @Autowired
    public RepositoryDocumentDao(
    ) {
        this.lock = new ReentrantLock();
    }
}

我的相关代码是:

代码语言:javascript
复制
private boolean verifyStorageSize(long requiredBytes) {
    this.lock.lock();
    LOG.debug("IN");
    //.. do someting large
    LOG.debug("OUT");
    this.lock.unlock();
}

我查看了日志,并在受保护的代码中输入了两个线程:

代码语言:javascript
复制
http-nio-8080-exec-3 =================IN=================  
...
http-nio-8080-exec-10 =================IN================= 

有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2020-03-10 13:07:52

--我无法重现您提到的的情况,但我为您提供了一个简单的示例,说明了如何实现代码。

代码语言:javascript
复制
    @RestController
    @RequestMapping("/event")
    public class EventRestController extends BaseRestController {

        private final EventService service;

        @Autowired
        public EventRestController(final EventService service) {
            this.service = requireNonNull(service, "service can't be null");
        }

        @PutMapping(value = "/sync")
        public Callable<ResponseEntity<Void>> syncOperation() {
            return () -> service.syncOperation();
        }
    ...
    }

    @Service
    @Slf4j
    public class EventServiceImpl implements EventService {

        private final EventRepository repository;
        private final ReentrantLock fairLock;

        @Autowired
        public EventServiceImpl(@Qualifier("eventRepository") final EventRepository repository) {
            this.repository = requireNonNull(repository, "repository can't be null");
            this.fairLock = new ReentrantLock(true);
        }

        @Override
        public void syncOperation() {
            log.debug("thread try to acquire lock");
            boolean isLockAcquired = false;
            try {
               isLockAcquired = fairLock.tryLock(10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
               throw new IllegalStateException(e);
            }

            if (isLockAcquired) {
               try {
                  log.debug("{} own the lock", Thread.currentThread().getName());
                  // heavy operation
                  Thread.sleep(2000);
               } catch (InterruptedException e) {
                  throw new IllegalStateException(e);
               } finally {
                  fairLock.unlock();
                  log.debug("thread unlock");
               }
           }

           log.debug("thread - {} end of method", Thread.currentThread().getName());
       }
    ...
}

Bash代码调用端点:

代码语言:javascript
复制
#!/bin/bash

MAX=$1

for (( c=1; c<=MAX; c++ ))
do
   curl -X PUT http://localhost:2000/app/event/sync > /dev/null 2>&1 &
done

调用:

代码语言:javascript
复制
./sync.sh 5

它将在后台启动5个进程,5个并发进程将调用端点。

日志消息:

代码语言:javascript
复制
15:59:22.026 [task-1] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread try to aquire lock
15:59:22.026 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread try to aquire lock
15:59:22.026 [task-3] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread try to aquire lock
15:59:22.026 [task-5] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread try to aquire lock
15:59:22.026 [task-4] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread try to aquire lock
15:59:22.026 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - task-2 own the lock
15:59:24.027 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread unlock
15:59:24.027 [task-3] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - task-3 own the lock
15:59:24.027 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread - task-2 end of method
15:59:26.027 [task-3] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread unlock
15:59:26.028 [task-3] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread - task-3 end of method
15:59:26.028 [task-1] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - task-1 own the lock
15:59:28.029 [task-1] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread unlock
15:59:28.029 [task-5] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - task-5 own the lock
15:59:28.029 [task-1] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread - task-1 end of method

在这个示例中,我们可以看到任务-2线程成功地获得了锁,其他线程试图锁定,直到任务-2释放锁为止,而线程-4没有在适当的时间获得锁。

我觉得这部分很有趣:

代码语言:javascript
复制
15:59:22.026 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - task-2 own the lock
15:59:24.027 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread unlock
15:59:24.027 [task-3] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - task-3 own the lock
15:59:24.027 [task-2] DEBUG hu.gaszabo.persistence.app.application.EventServiceImpl - thread - task-2 end of method

任务-2线程获得了锁,2秒后它释放了锁,任务-3线程在任务之前立即获得了锁-2线程扭曲了“方法的结束”消息。

您的问题的答案可以是,某些操作是在同一时间发生的(查看时间戳会更好),但它会按照日志中的顺序向您显示您可能误解的内容(例如,我显示的内容代表了这种情况)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60616540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档