线程的状态:
1.新建(new) :分配了系统必要的资源,并执行了初始化,有资格获得CPU时间了
2.就绪(runnable):只要获得时间片就能执行
3. 阻塞(Blocked): 线程能够运行但被某个条件终止,不会分配CPU时间
4.死亡(Dead):处于死亡状态的线程不能调度,不会得到CPU时间片
进入阻塞的原因:
1.sleep() ---------->>可中断阻塞
2.调用wait()使线程挂起
3.I/O操作 ---------------->>不可中断 但是!!! 使用新nio类中俄SocketChannel可以中断
4. 任务视图在某个对象上调用其同步控制方法,但对象锁不可用--------------------->>不可中断 但是!!!!使用ReetrantLock可以中断
具体代码如下:
package Number_2102;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* 阻塞和终端
*
* @author he
*
*/
// sleep()阻塞
class sleepBlocked implements Runnable {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("InterruptedException");
}
System.out.println("Exiting SleepBlocked .run()");
}
}
// I/O阻塞
class ioBlocked implements Runnable {
private InputStream ip;
ioBlocked(InputStream ip) {
this.ip = ip;
}
public void run() {
try {
System.out.println("Waiting for read()");
ip.read();
} catch (IOException e) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("线程被中断");
} else {
throw new RuntimeException();
}
System.out.println("Exiting IOBlocked.run()");
}
}
}
class SyncBlocked implements Runnable {
public synchronized static void f() {
while (true) {
Thread.yield();
}
}
public SyncBlocked() {
new Thread() {
public void run() {
f(); // 因为外部的run不会终止 所以此方法永远不会执行
};
}.start();
}
public void run() {
System.out.println("Try to call of f()");
f();
System.out.println("Exiting SycncBlocked.run()");
}
}
public class P696 {
protected static ExecutorService eService = Executors.newCachedThreadPool();
static void test(Runnable r) throws Exception {
Future<?> f = eService.submit(r);
TimeUnit.MICROSECONDS.sleep(100);
// 打印终止线程的名字
System.out.println("Interrupt:" + r.getClass().getName());
f.cancel(true);
System.out.println("Interrupt sent to " + r.getClass().getName());
}
public static void main(String[] args) throws Exception {
test(new sleepBlocked());
test(new ioBlocked(System.in));
test(new SyncBlocked());
TimeUnit.MICROSECONDS.sleep(1000);
System.out.println(" System.exit()");
System.exit(0);
}
}
package Number_2102;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* nio类提供的I/O中断
*
* @author he
*
*/
class NIOBlocked implements Runnable {
private final SocketChannel sc;
public NIOBlocked(SocketChannel sc) {
// TODO Auto-generated constructor stub
this.sc = sc;
}
public void run() {
try {
System.out.println("Waiting for read()" +this);
sc.read(ByteBuffer.allocate(1));
} catch (IOException e) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("I/O 线程被中断");
}
}
}
@Override
public String toString() {
// TODO Auto-generated method stub
return sc.getClass().getName()+ this.hashCode();
}
}
public class P698 {
public static void main(String[] args) throws IOException, InterruptedException {
ExecutorService eService = Executors.newCachedThreadPool();
ServerSocket socket = new ServerSocket(8080);
InetSocketAddress isa = new InetSocketAddress("localhost", 8080);
SocketChannel sc1 = SocketChannel.open(isa);
SocketChannel sc2 = SocketChannel.open(isa);
Future<?> future = eService.submit(new NIOBlocked(sc1));
eService.submit(new NIOBlocked(sc2));
eService.shutdown();
TimeUnit.SECONDS.sleep(2);
future.cancel(true);
TimeUnit.SECONDS.sleep(1);
sc2.close();
}
}
使用ReentrantLock:
package Number_2102;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 在ReentrantLock上阻塞的任务具备可以被中断的能力
*
* @author he
*
*/
class BlockedMutex {
private Lock lock = new ReentrantLock();
public BlockedMutex() {
// TODO Auto-generated constructor stub
// 上锁
lock.lock();
}
public void f() {
// 如果线程未被中断获取锁
try {
// lock.lockInterruptibly();
System.out.println("lock acquired in f()");
}
// InterruptedException
// 当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常。
finally {
if (Thread.currentThread().isInterrupted()) {
System.out.println("线程被中断");
}
}
}
}
class Blocked2 implements Runnable {
BlockedMutex b = new BlockedMutex();
public void run() {
// TODO Auto-generated method stub
System.out.println("Wating for f() in BlockedMutex");
// 由于BlockedMutex被上锁且不释放 所以b.f()永远无法执行
b.f();
}
}
public class P700 {
public static void main(String[] args) {
Thread t = new Thread(new Blocked2());
t.start();
t.interrupt();
}
}
检查中断:
当你在线程上调用interrupt()时,中断发生的唯一时刻是在任务要进入到阻塞中或者已经在足赛操作的内部时。