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:
parent
9e995c1e41
commit
14070ec048
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue