package com.interview.basics.java.cocurrency;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created with IntelliJ IDEA.
* User: stefanie
* Date: 12/24/14
* Time: 2:55 PM
* <p/>
* IOBlockedTask and SynchronizedBlockedTask can't be interrupted to shutdown.
* For IOBlockedTask, we could close IO stream to shutdown the thread.
* And in NIO, the blocked IO can handle interruption.
* For SynchronizedBlockedTask, it can't be interrupted, but ReentrantLock can using lock.lockInterruptibly().
*/
public class ThreadInterruptSample {
static class SleepBlockedTask implements Runnable {
@Override
public void run() {
try {
System.out.println("Sleep 100 seconds");
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
System.err.println("SleepBlockedTask is interrupted");
}
System.out.println("Exit from SleepBlockedTask");
}
}
static class IOBlockedTask implements Runnable {
private InputStream in;
public IOBlockedTask(InputStream is) {
in = is;
}
@Override
public void run() {
try {
System.out.println("Waiting for read()");
in.read();
} catch (IOException e) {
if (Thread.currentThread().isInterrupted()) {
System.err.println("IOBlockedTask is interrupted");
} else {
throw new RuntimeException(e);
}
}
System.out.println("Exit from IOBlockedTask");
}
}
static class SynchronizedBlockedTask implements Runnable {
public synchronized void f() {
while (true) Thread.yield();
}
public SynchronizedBlockedTask() {
new Thread() {
public void run() {
f();
}
}.start();
}
@Override
public void run() {
System.out.println("SynchronizedBlockedTask Trying to call f()");
f();
System.out.println("Exit from SynchronizedBlockedTask");
}
}
static class ReentrantLockBlockTask implements Runnable {
private Lock lock = new ReentrantLock();
public ReentrantLockBlockTask() {
lock.lock();
}
public void f() {
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
System.err.println("ReentrantLockBlockTask is interrupted");
}
System.out.println("Exit from ReentrantLockBlockTask");
}
@Override
public void run() {
System.out.println("ReentrantLockBlockTask Trying to call f()");
f();
}
}
static class InterruptedTask implements Runnable {
@Override
public void run() {
double d = 1.0;
while (!Thread.interrupted()) { //
for (int i = 0; i < 25000000; i++) d = d + (Math.PI + Math.E) / d;
System.out.println(d);
}
System.err.println("InterruptedTask is interrupted");
System.out.println("Exit from InterruptedTask");
}
}
static class InterruptThread {
public static void testThreadInterrupt(Runnable runnable) throws InterruptedException {
Thread thread = new Thread(runnable);
thread.start();
TimeUnit.SECONDS.sleep(1);
thread.interrupt();
}
public static void main(String[] args) throws InterruptedException {
testThreadInterrupt(new SleepBlockedTask());
testThreadInterrupt(new IOBlockedTask(System.in));
testThreadInterrupt(new SynchronizedBlockedTask());
TimeUnit.SECONDS.sleep(3);
System.exit(0);
}
}
static class InterruptExecutorService {
public static void testInterruptExecutorService(Runnable runnable) throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
Future<?> f = exec.submit(runnable);
TimeUnit.SECONDS.sleep(1);
f.cancel(true);
}
public static void main(String[] args) throws InterruptedException {
testInterruptExecutorService(new SleepBlockedTask());
testInterruptExecutorService(new IOBlockedTask(System.in));
testInterruptExecutorService(new SynchronizedBlockedTask());
testInterruptExecutorService(new ReentrantLockBlockTask());
testInterruptExecutorService(new InterruptedTask());
TimeUnit.SECONDS.sleep(3);
System.exit(0);
}
}
static class ShutdownIOBlockedTask {
public static void main(String[] args) throws IOException, InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(8080);
InputStream socketInput = new Socket("localhost", 8080).getInputStream();
Future<?> f = exec.submit(new IOBlockedTask(socketInput));
TimeUnit.SECONDS.sleep(1);
f.cancel(true);
TimeUnit.SECONDS.sleep(1);
System.out.println("Try closing input stream");
socketInput.close();
TimeUnit.SECONDS.sleep(5);
System.exit(0);
}
}
}