Interrupt

interrupt()只是改变中断状态而已
interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
如果线程没有被阻塞,这时调用interrupt()将不起作用;如果想起作用,必须不断判断系统中断状态,例如:
package com.zte.cxm;

class ATask implements Runnable{

private double d = 0.0;

public void run() {

//检查程序是否发生中断
while (!Thread.interrupted()) {
System.out.println("I am running!");

for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
}

System.out.println("ATask.run() interrupted!");
}
}



public class InterruptTaskTest {

public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new Thread(new ATask());
t.start();

//运行一断时间中断线程
Thread.sleep(50);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}


线程A在执行sleep,wait,join时,线程B调用A的interrupt方法,的确这一个时候A会有InterruptedException异常抛出来.但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。
例如:
package com.zte.cxm;

class ATask implements Runnable{

private double d = 0.0;

public void run() {
//死循环执行打印"I am running!" 和做消耗时间的浮点计算
try {
while (true) {
System.out.println("I am running!");

for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
//休眠一断时间,中断时会抛出InterruptedException
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("ATask.run() interrupted!");
}
}
}


public class InterruptTaskTest {

public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new Thread(new ATask());
t.start();

//运行一断时间中断线程
Thread.sleep(50);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}



如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,都不会去检查中断状态,所以线程A不会抛出InterruptedException,而会一直执行着自己的操作.当线程A终于执行到wait(),sleep(),join()时,才马上会抛出InterruptedException.
比如:
package com.zte.cxm;

class ATask implements Runnable{

private double d = 0.0;

public void run() {
//死循环执行打印"I am running!" 和做消耗时间的浮点计算
try {



for (int i = 0; i < 5000; i++) {
System.out.println("I am running!"+i);
}
//休眠一断时间,中断时会抛出InterruptedException
Thread.sleep(50);
for (int i = 0; i < 1000; i++) {
System.out.println("He am running!"+i);
}

} catch (InterruptedException e) {
System.out.println("ATask.run() interrupted!");
}
}
}


public class InterruptTaskTest {

public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new Thread(new ATask());
t.start();

//运行一断时间中断线程
Thread.sleep(50);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}


若没有调用sleep(),wait(),join()这些方法,或是没有在线程里自己检查中断状态自己抛出InterruptedException的话,那InterruptedException是不会被抛出来的.


1. sleep() & interrupt()
线程A正在使用sleep()暂停着: Thread.sleep(100000);
如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B)调用
a.interrupt();
令线程A放弃睡眠操作,这里a是线程A对应到的Thread实例
执行interrupt()时,并不需要获取Thread实例的锁定.任何线程在任何时刻,都可以调用其他线程interrupt().当sleep中的线程被调用interrupt()时,就会放弃暂停的状态.并抛出InterruptedException.丢出异常的,是A线程.


2. wait() & interrupt()
线程A调用了wait()进入了等待状态,也可以用interrupt()取消.
不过这时候要小心锁定的问题.线程在进入等待区,会把锁定解除,当对等待中的线程调用interrupt()时(注意是等待的线程调用其自己的interrupt()),会先重新获取锁定,再抛出异常.在获取锁定之前,是无法抛出异常的.


http://zhangjunhd.blog.51cto.com/113473/71387


package com.zte.cxm;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


public class Game implements Runnable {
private Set<Athlete> players = new HashSet<Athlete>();
private boolean start = false;

public void addPlayer(Athlete one) {
players.add(one);
}

public void removePlayer(Athlete one) {
players.remove(one);
}

public Collection<Athlete> getPlayers() {
return Collections.unmodifiableSet(players);
}

public void prepare(Athlete athlete) throws InterruptedException {
System.out.println(athlete + " ready!");
synchronized (this) {
while (!start)
wait();
if (start)
System.out.println(athlete + " go!");
}
}

public synchronized void go() {
notifyAll();
}
public void ready() {
Iterator<Athlete> iter = getPlayers().iterator();
while (iter.hasNext())
new Thread(iter.next()).start();
}

public void run() {
start = false;
System.out.println("Ready......");
System.out.println("Ready......");
System.out.println("Ready......");
ready();
start = true;
System.out.println("Go!");
go();
}

public static void main(String[] args) {
Game game = new Game();
for (int i = 0; i < 10; i++)
game.addPlayer(new Athlete(i, game));
new Thread(game).start();
}
}


class Athlete implements Runnable {
private final int id;
private Game game;

public Athlete(int id, Game game) {
this.id = id;
this.game = game;
}

public boolean equals(Object o) {
if (!(o instanceof Athlete))
return false;
Athlete athlete = (Athlete) o;
return id == athlete.id;
}

public String toString() {
return "Athlete<" + id + ">";
}

public int hashCode() {
return new Integer(id).hashCode();
}

public void run() {
try {
game.prepare(this);
} catch (InterruptedException e) {
System.out.println(this + " quit the game");
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值