awslabs / amazon-dynamodb-lock-client

The AmazonDynamoDBLockClient is a general purpose distributed locking library built on top of DynamoDB. It supports both coarse-grained and fine-grained locking.
Other
476 stars 87 forks source link

Why multi-threading is blocking with configuing withShouldSkipBlockingWait = True #103

Open Kiollpt opened 1 month ago

Kiollpt commented 1 month ago

main

  ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(new CakeEater(lockClient, "User 1", 20000));
        executorService.submit(new CakeEater(lockClient, "User 2",10000));

CakeEater

static class CakeEater implements Runnable {
        private final AmazonDynamoDBLockClient lockClient;
        private final String userName;
        private final long eatingSpeed;

        public CakeEater(AmazonDynamoDBLockClient lockClient, String userName, long eatingSpeed) {
            this.lockClient = lockClient;
            this.userName = userName;
            this.eatingSpeed = eatingSpeed;
        }

        @Override
        public void run(){

            if (cakePieces > 0) {

                final Optional<LockItem> lockItem;
              try {
                  System.out.println(userName + ": trying to get lock");

                  lockItem =
                          lockClient.tryAcquireLock(AcquireLockOptions.builder(PARTITION_KEY).withShouldSkipBlockingWait(true).build());
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }

              if (lockItem.get() != null ) {
                  System.out.println(userName + " got key: " + lockItem);

                  try {
                      Thread.sleep(eatingSpeed); // Simulate eating time
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }

                  cakePieces -= 1;
                  System.out.println(userName + " ate a piece of cake. Remaining pieces: " + cakePieces);
                  lockClient.releaseLock(lockItem.get());

              } else
              {
                  System.out.println(userName + " is waiting a lock");
                  try {
                      throw new Exception("lock is held by other");
                  } catch (Exception e) {
                      throw new RuntimeException(e);
                  }
              }

            }
        }

    }
}
Sep 09, 2024 12:26:26 AM io.harry.utils.DynamoDbClientTest$CakeEater run
INFO: User 2: trying to get lock
Sep 09, 2024 12:26:26 AM io.harry.utils.DynamoDbClientTest$CakeEater run
INFO: User 1: trying to get lock
Sep 09, 2024 12:26:27 AM io.harry.utils.DynamoDbClientTest$CakeEater run
INFO: User 1 got key: Optional[LockItem{Partition Key=key, Sort Key=Optional.empty, Owner Name=HG976G70QVf8210aae-73ff-45c8-9a19-4c541e5925ff, Lookup Time=917462271, Lease Duration=50000, Record Version Number=0269d63d-8844-40e5-8cdc-80289cf92326, Delete On Close=true, Data=, Is Released=false}]
Sep 09, 2024 12:26:47 AM io.harry.utils.DynamoDbClientTest$CakeEater run
INFO: User 1 ate a piece of cake. Remaining pieces: 9

I was expecting use2 raise exception after user 1 got the lock

shetsa-amzn commented 2 weeks ago

We have merged the latest commit from @moshegood and this change has been release in version 1.3.