Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧靴:可重入锁定_Java_Spring_Spring Boot_Synchronization_Distributed Computing - Fatal编程技术网

Java 弹簧靴:可重入锁定

Java 弹簧靴:可重入锁定,java,spring,spring-boot,synchronization,distributed-computing,Java,Spring,Spring Boot,Synchronization,Distributed Computing,我已经编写了一个@Repository类: @Repository public class RepositoryDocumentDao { private static final Logger LOG = LoggerFactory.getLogger(RepositoryDocumentDao.class); private ReentrantLock lock; @Autowired public RepositoryDocumentDao(

我已经编写了一个
@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();
}
我查看了日志,两个线程进入了受保护的代码中:

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());
       }
    ...
}
它将在后台启动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线程发出“方法结束”消息之前立即获得了锁


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

或者它们没有使用相同的锁,或者他们没有同时获得锁。你说“同时”是什么意思?锁是互斥的,所以如果你说两个线程获得了同一个锁,它不可能同时发生(除非
ReentrantLock
从根本上被破坏了,而事实并非如此)。所以您有两种选择:多个锁或误读日志消息。我很惊讶你在存储库中使用了
ReentrantLock
,听起来很可疑。
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
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