1
0
This commit is contained in:
2024-11-14 13:36:37 +03:00
parent 5bae7a279b
commit 6a61a96a16
6 changed files with 82 additions and 59 deletions

View File

@@ -13,29 +13,33 @@ public class MyCountDownLatch {
}
public void countDown() {
synchronized (lock) {
if (count <= 0)
synchronized (this.lock) {
if (this.count <= 0)
return;
count--;
this.count--;
if (count == 0) {
lock.notifyAll();
if (this.count == 0) {
this.lock.notifyAll();
}
}
}
public void await() throws InterruptedException {
synchronized (lock) {
while (count > 0) {
lock.wait();
synchronized (this.lock) {
while (this.count > 0) {
this.lock.wait();
}
}
}
public boolean tryAwait() {
return this.getCount() <= 0;
}
public int getCount() {
synchronized (lock) {
return count;
synchronized (this.lock) {
return this.count;
}
}
}

View File

@@ -8,48 +8,49 @@ public class MyReentrantLock {
private Thread owner;
public void lock() throws InterruptedException {
synchronized (lock) {
synchronized (this.lock) {
Thread current = Thread.currentThread();
while (isLocked() && current != owner) {
lock.wait();
while (isLocked() && current != this.owner) {
this.lock.wait();
}
counter++;
owner = current;
this.counter++;
this.owner = current;
}
}
public boolean tryLock() {
synchronized (lock) {
synchronized (this.lock) {
Thread current = Thread.currentThread();
if (isLocked() && current != owner) {
if (isLocked() && current != this.owner) {
return false;
}
this.counter++;
this.owner = current;
counter++;
owner = current;
return true;
}
}
public void unlock() {
synchronized (lock) {
if (Thread.currentThread() != owner) {
synchronized (this.lock) {
if (Thread.currentThread() != this.owner) {
throw new IllegalMonitorStateException("Not owner");
}
this.counter--;
counter--;
if (counter == 0) {
owner = null;
lock.notify();
if (this.counter == 0) {
this.owner = null;
this.lock.notify();
}
}
}
private boolean isLocked() {
return counter > 0;
return this.counter > 0;
}
}

View File

@@ -10,36 +10,37 @@ public class MySemaphore {
}
public void acquire() throws InterruptedException {
synchronized (lock) {
while (permits <= 0) {
lock.wait();
synchronized (this.lock) {
while (this.permits <= 0) {
this.lock.wait();
}
permits--;
this.permits--;
}
}
public boolean tryAcquire() {
synchronized (lock) {
if (permits <= 0) {
synchronized (this.lock) {
if (this.permits <= 0) {
return false;
}
permits--;
this.permits--;
return true;
}
}
public void release() {
synchronized (lock) {
permits++;
lock.notify();
synchronized (this.lock) {
this.permits++;
this.lock.notify();
}
}
public int availablePermits() {
synchronized (lock) {
return permits;
synchronized (this.lock) {
return this.permits;
}
}
}

View File

@@ -1,3 +1,4 @@
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import ru.lionarius.sync.MyCountDownLatch;
@@ -30,7 +31,7 @@ class MyCountDownLatchTest {
assertEquals(0, latch.getCount());
}
@Test
@RepeatedTest(20)
void testAwait() throws InterruptedException {
var latch = new MyCountDownLatch(2);
var threadFinished = new AtomicBoolean(false);
@@ -39,8 +40,7 @@ class MyCountDownLatchTest {
try {
latch.await();
threadFinished.set(true);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (InterruptedException ignored) {
}
});
@@ -58,6 +58,7 @@ class MyCountDownLatchTest {
}
@Test
@Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
void testMultipleThreads() throws InterruptedException {
final int THREAD_COUNT = 5;
var startLatch = new MyCountDownLatch(1);
@@ -76,8 +77,7 @@ class MyCountDownLatchTest {
Thread.sleep(100);
threadsFinished[index].set(true);
endLatch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (InterruptedException ignored) {
}
}).start();
}
@@ -106,7 +106,6 @@ class MyCountDownLatchTest {
void testZeroCount() throws InterruptedException {
var latch = new MyCountDownLatch(0);
assertEquals(0, latch.getCount());
latch.await();
assertTrue(true);
assertTrue(latch.tryAwait());
}
}

View File

@@ -25,6 +25,11 @@ class MyReentrantLockTest {
lock.unlock();
}
@Test
void testUnlock() {
assertThrows(IllegalMonitorStateException.class, lock::unlock);
}
@Test
@Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
void testTryLock() throws InterruptedException {
@@ -68,11 +73,11 @@ class MyReentrantLockTest {
threads[i] = new Thread(() -> {
try {
lock.lock();
Thread.sleep(10);
lock.unlock();
threadsCompleted[index].set(true);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (InterruptedException ignored) {
}
finally {
lock.unlock();
}
});
threads[i].start();

View File

@@ -46,9 +46,12 @@ class MySemaphoreTest {
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);
@@ -57,14 +60,17 @@ class MySemaphoreTest {
try {
startLatch.await();
semaphore.acquire();
int current = concurrentThreads.incrementAndGet();
maxConcurrentThreads.updateAndGet(max -> Math.max(max, current));
Thread.sleep(100); // Имитация работы
Thread.sleep(100);
concurrentThreads.decrementAndGet();
semaphore.release();
finishLatch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (InterruptedException ignored) {
}
}).start();
}
@@ -80,22 +86,29 @@ class MySemaphoreTest {
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 e) {
Thread.currentThread().interrupt();
} catch (InterruptedException ignored) {
}
doneLatch.countDown();
});
thread.start();
Thread.sleep(100); // Даем время потоку начать ожидание
startLatch.await();
assertTrue(thread.isAlive());
assertEquals(0, semaphore.availablePermits());
semaphore.release();
thread.join(1000);
doneLatch.await();
assertFalse(thread.isAlive());
assertEquals(0, semaphore.availablePermits());
}