126 lines
4.0 KiB
Java
126 lines
4.0 KiB
Java
import org.junit.jupiter.api.Test;
|
|
import ru.lionarius.sync.MySemaphore;
|
|
|
|
import java.util.concurrent.CountDownLatch;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
class MySemaphoreTest {
|
|
@Test
|
|
void testInitialization() {
|
|
assertDoesNotThrow(() -> new MySemaphore(-1));
|
|
assertDoesNotThrow(() -> new MySemaphore(0));
|
|
var semaphore = new MySemaphore(5);
|
|
assertEquals(5, semaphore.availablePermits());
|
|
}
|
|
|
|
@Test
|
|
void testAcquireAndRelease() throws InterruptedException {
|
|
var semaphore = new MySemaphore(2);
|
|
assertEquals(2, semaphore.availablePermits());
|
|
semaphore.acquire();
|
|
assertEquals(1, semaphore.availablePermits());
|
|
semaphore.acquire();
|
|
assertEquals(0, semaphore.availablePermits());
|
|
assertFalse(semaphore.tryAcquire());
|
|
semaphore.release();
|
|
assertEquals(1, semaphore.availablePermits());
|
|
assertTrue(semaphore.tryAcquire());
|
|
assertEquals(0, semaphore.availablePermits());
|
|
}
|
|
|
|
@Test
|
|
void testTryAcquire() {
|
|
var semaphore = new MySemaphore(2);
|
|
assertTrue(semaphore.tryAcquire());
|
|
assertEquals(1, semaphore.availablePermits());
|
|
assertTrue(semaphore.tryAcquire());
|
|
assertEquals(0, semaphore.availablePermits());
|
|
assertFalse(semaphore.tryAcquire());
|
|
assertEquals(0, semaphore.availablePermits());
|
|
}
|
|
|
|
@Test
|
|
void testMultipleThreads() throws InterruptedException {
|
|
final int THREAD_COUNT = 10;
|
|
final int PERMITS = 3;
|
|
|
|
var semaphore = new MySemaphore(PERMITS);
|
|
|
|
var startLatch = new CountDownLatch(1);
|
|
var finishLatch = new CountDownLatch(THREAD_COUNT);
|
|
|
|
var concurrentThreads = new AtomicInteger(0);
|
|
var maxConcurrentThreads = new AtomicInteger(0);
|
|
|
|
for (int i = 0; i < THREAD_COUNT; i++) {
|
|
new Thread(() -> {
|
|
try {
|
|
startLatch.await();
|
|
semaphore.acquire();
|
|
|
|
int current = concurrentThreads.incrementAndGet();
|
|
maxConcurrentThreads.updateAndGet(max -> Math.max(max, current));
|
|
|
|
Thread.sleep(100);
|
|
|
|
concurrentThreads.decrementAndGet();
|
|
|
|
semaphore.release();
|
|
finishLatch.countDown();
|
|
} catch (InterruptedException ignored) {
|
|
}
|
|
}).start();
|
|
}
|
|
|
|
startLatch.countDown();
|
|
assertTrue(finishLatch.await(5, TimeUnit.SECONDS));
|
|
assertEquals(PERMITS, maxConcurrentThreads.get());
|
|
assertEquals(PERMITS, semaphore.availablePermits());
|
|
}
|
|
|
|
@Test
|
|
void testBlockingAcquire() throws InterruptedException {
|
|
var semaphore = new MySemaphore(1);
|
|
semaphore.acquire();
|
|
assertEquals(0, semaphore.availablePermits());
|
|
|
|
var startLatch = new CountDownLatch(1);
|
|
var doneLatch = new CountDownLatch(1);
|
|
var thread = new Thread(() -> {
|
|
try {
|
|
startLatch.countDown();
|
|
|
|
semaphore.acquire();
|
|
} catch (InterruptedException ignored) {
|
|
}
|
|
|
|
doneLatch.countDown();
|
|
});
|
|
|
|
thread.start();
|
|
startLatch.await();
|
|
|
|
assertTrue(thread.isAlive());
|
|
assertEquals(0, semaphore.availablePermits());
|
|
|
|
semaphore.release();
|
|
doneLatch.await();
|
|
|
|
assertFalse(thread.isAlive());
|
|
assertEquals(0, semaphore.availablePermits());
|
|
}
|
|
|
|
@Test
|
|
void testAvailablePermits() {
|
|
var semaphore = new MySemaphore(5);
|
|
assertEquals(5, semaphore.availablePermits());
|
|
semaphore.tryAcquire();
|
|
assertEquals(4, semaphore.availablePermits());
|
|
semaphore.release();
|
|
assertEquals(5, semaphore.availablePermits());
|
|
}
|
|
}
|