BAEL-6139: Added ThreadMonitorInfo (#15094)

* BAEL-6139: Added ThreadMonitorInfo

* BAEL-6139: Move ThreadMonitorInfo

* BAEL-6139: Unsafe using park() and unpark(Thread)
This commit is contained in:
Eugene Kovko 2023-11-07 04:50:48 +01:00 committed by GitHub
parent 9e995c1e41
commit 14070ec048
5 changed files with 203 additions and 0 deletions

View File

@ -0,0 +1,26 @@
package com.baeldung.park;
import java.util.concurrent.locks.LockSupport;
public class ThreadMonitorInfo {
private static final Object MONITOR = new Object();
public static void main(String[] args) throws InterruptedException {
final Thread waitingThread = new Thread(() -> {
try {
synchronized (MONITOR) {
MONITOR.wait();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, "Waiting Thread");
final Thread parkedThread = new Thread(LockSupport::park, "Parked Thread");
waitingThread.start();
parkedThread.start();
waitingThread.join();
parkedThread.join();
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.park;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.locks.LockSupport;
import org.junit.jupiter.api.Test;
class PreemptivePermitsBehaviorUnitTest {
private final Thread parkedThread = new Thread() {
@Override
public void run() {
LockSupport.unpark(this);
LockSupport.park();
}
};
@Test
void givenThreadWhenPreemptivePermitShouldNotPark() {
assertTimeoutPreemptively(Duration.of(1, ChronoUnit.SECONDS), () -> {
parkedThread.start();
parkedThread.join();
});
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.park;
import static org.junit.jupiter.api.Assertions.assertFalse;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.LockSupport;
import org.junit.jupiter.api.Test;
class RepeatedPreemptivePermitsBehaviorUnitTest {
private final Thread parkedThread = new Thread() {
@Override
public void run() {
LockSupport.unpark(this);
LockSupport.unpark(this);
LockSupport.park();
LockSupport.park();
}
};
@Test
void givenThreadWhenRepeatedPreemptivePermitShouldPark() {
Callable<Boolean> callable = () -> {
parkedThread.start();
parkedThread.join();
return true;
};
boolean result = false;
final Future<Boolean> future = Executors.newSingleThreadExecutor().submit(callable);
try {
result = future.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
// Expected the thread to be parked
}
assertFalse(result, "The thread should be parked");
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.park;
import static org.junit.jupiter.api.Assertions.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
class ThreadInterruptedBehaviorUnitTest {
@Test
@Timeout(3)
void givenParkedThreadWhenInterruptedShouldNotResetInterruptedFlag() throws InterruptedException {
final Thread thread = new Thread(LockSupport::park);
thread.start();
thread.interrupt();
assertTrue(thread.isInterrupted(), "The thread should have the interrupted flag");
thread.join();
}
@Test
@Timeout(3)
void givenParkedThreadWhenNotInterruptedShouldNotHaveInterruptedFlag() throws InterruptedException {
final Thread thread = new Thread(LockSupport::park);
thread.start();
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
LockSupport.unpark(thread);
assertFalse(thread.isInterrupted(), "The thread shouldn't have the interrupted flag");
thread.join();
}
@Test
@Timeout(3)
void givenWaitingThreadWhenNotInterruptedShouldNotHaveInterruptedFlag() throws InterruptedException {
final Thread thread = new Thread() {
@Override
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
// The thread was interrupted
}
}
}
};
thread.start();
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
thread.interrupt();
thread.join();
assertFalse(thread.isInterrupted(), "The thread shouldn't have the interrupted flag");
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.park;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
class TreadMonitorsBehaviorUnitTest {
@Test
@Timeout(3)
void giveThreadWhenNotifyWithoutAcquiringMonitorThrowsException() {
final Thread thread = new Thread() {
@Override
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
// The thread was interrupted
}
}
}
};
assertThrows(IllegalMonitorStateException.class, () -> {
thread.start();
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
thread.notify();
thread.join();
});
}
@Test
@Timeout(3)
void giveThreadWhenUnparkWithoutAcquiringMonitor() {
final Thread thread = new Thread(LockSupport::park);
assertTimeoutPreemptively(Duration.of(2, ChronoUnit.SECONDS), () -> {
thread.start();
LockSupport.unpark(thread);
});
}
}