gpt4 book ai didi

java - Spring 启动: ReentrantLock

转载 作者:行者123 更新时间:2023-12-01 18:01:45 25 4
gpt4 key购买 nike

我编写了一个 @Repository 类:

@Repository
public class RepositoryDocumentDao {

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

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

我的相关代码是:

private boolean verifyStorageSize(long requiredBytes) {
this.lock.lock();
LOG.debug("IN");
//.. do someting large
LOG.debug("OUT");
this.lock.unlock();
}

我查看了日志,发现两个线程已进入 protected 代码:

http-nio-8080-exec-3 =================IN=================  
...
http-nio-8080-exec-10 =================IN=================

有什么想法吗?

最佳答案

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

    @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 代码调用端点:

#!/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

调用:

./sync.sh 5

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

日志消息:

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

在示例中,我们可以看到 task-2 线程成功获取锁,其他线程尝试获取锁,但它们被阻塞,直到 >task-2释放了锁,而thread-4没有在适当的时间获得锁。

我认为这部分很有趣:

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

task-2线程获得锁,2秒后释放锁,task-3线程在 task-2 线程写入“方法结束”消息之前立即获得锁定。

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

关于java - Spring 启动: ReentrantLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60616540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com