import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class JavaStopGraceFully {
public static int len = 5;
static ArrayBlockingQueue queue = new ArrayBlockingQueue<>(1000);
static ExecutorService executorService = Executors.newFixedThreadPool(3);
static volatile AtomicBoolean stopPut = new AtomicBoolean(false);
static volatile AtomicBoolean stopPoll = new AtomicBoolean(false);
static volatile AtomicBoolean readyExitFlag = new AtomicBoolean(false);
public static void main(String[] args) throws InterruptedException {
executorService.submit(new Runnable() {
@Override
public void run() {
while (true) {
for (int i = 0; i < len + 1; i++) {
try {
queue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
TimeUnit.SECONDS.sleep(len);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (stopPut.get()) {
break;
}
}
System.out.println("exit put thread.");
}
});
executorService.submit(new Runnable() {
@Override
public void run() {
while (true) {
Integer ele = queue.poll();
System.out.println(ele);
try {
TimeUnit.SECONDS.sleep(1L);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (stopPoll.get()) {
break;
}
}
System.out.println("exit poll thread.");
}
});
executorService.submit(new Runnable() {
@Override
public void run() {
while (true) {
if (!stopPut.get()) {
continue;
}
if (stopPut.get()) {
if (0 == queue.size()) {
stopPoll.set(true);
readyExitFlag.set(true);
}
}
if (readyExitFlag.get()) {
break;
}
try {
TimeUnit.SECONDS.sleep(1L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("exit loop thread.");
if (readyExitFlag.get()) {
System.out.println("exit gracefully.");
System.exit(0);
}
}
});
SignalHandler sh = new SignalHandler() {
@Override
public void handle(Signal signal) {
System.out
.println(signal.getName() + ".." + signal.getNumber());
if (signal.getName().equals("INT")
|| signal.getName().equals("TERM")) {
if (readyExitFlag.get()) {
System.out.println("exit gracefully.");
System.exit(0);
} else {
if (stopPut.get()) {
System.out.println("wait for pop done.");
} else {
stopPut.set(true);
}
}
}
}
};
Signal.handle(new Signal(System.getProperties().getProperty("os.name")
.toLowerCase().startsWith("win") ? "INT" : "TERM"), sh);
}
}