看这段代码:
很简单, 20000个线程, 名字是thread1 ~ thread10000和thread1-sleep ~ thread10000-sleep。
每个threadi-sleep会睡1秒钟,同时threadi会中断它。
public class InterruptTest {
public static void main(String[] args) throws Exception {
for (int i = 1; i <= 10000; i++) {
Thread t = new Interrupt();
t.setName("thread" + i);
t.start();
}
}
private static class Interrupt extends Thread {
public void run() {
Thread t = new Sleep();
t.setName( getName() + "-sleep" );
t.start();
t.interrupt();
System.out.println( System.currentTimeMillis() + " " +
t.getName() + " " + t.isInterrupted() );
}
}
private static class Sleep extends Thread {
public void run() {
try {
Thread.sleep(1000);
} catch (Exception e) {
return;
}
System.err.println( System.currentTimeMillis() + " No! " +
getName() + " " + isInterrupted() );
}
}
}我以为最后一句System.err.println()不可能被执行到,因为上面的Thread.sleep()肯定会被中断,然后就到了return。但是stderr里却实有输出:
1304393164531 No! thread949-sleep true
1304393164562 No! thread1128-sleep false不是每次运行都发生,好像是偶尔才发生。
可以看到,我在每次interrupt()语句后面,都向stdout输出一行。然后我在stdout里面找到了这两行输出,把它们和上面的输出放在一起看:
1304393163531 thread949-sleep true
1304393164531 No! thread949-sleep true
1304393163562 thread1128-sleep true
1304393164562 No! thread1128-sleep false可以看到,这两个interrupt()语句已经执行完了,而且是在stderr输出的1秒钟前。那么,为什么这两个sleep()没有被中断?P.S. 我在3台电脑上运行了这个程序很多次,3台都是Windows XP。上述情况只在其中两台发生,这两台都是酷睿双核 2.4GHz。在另一台电脑上没有发生,那台是赛扬 1.5GHz。它们的JDK版本都完全相同,都是1.6。
很简单, 20000个线程, 名字是thread1 ~ thread10000和thread1-sleep ~ thread10000-sleep。
每个threadi-sleep会睡1秒钟,同时threadi会中断它。
public class InterruptTest {
public static void main(String[] args) throws Exception {
for (int i = 1; i <= 10000; i++) {
Thread t = new Interrupt();
t.setName("thread" + i);
t.start();
}
}
private static class Interrupt extends Thread {
public void run() {
Thread t = new Sleep();
t.setName( getName() + "-sleep" );
t.start();
t.interrupt();
System.out.println( System.currentTimeMillis() + " " +
t.getName() + " " + t.isInterrupted() );
}
}
private static class Sleep extends Thread {
public void run() {
try {
Thread.sleep(1000);
} catch (Exception e) {
return;
}
System.err.println( System.currentTimeMillis() + " No! " +
getName() + " " + isInterrupted() );
}
}
}我以为最后一句System.err.println()不可能被执行到,因为上面的Thread.sleep()肯定会被中断,然后就到了return。但是stderr里却实有输出:
1304393164531 No! thread949-sleep true
1304393164562 No! thread1128-sleep false不是每次运行都发生,好像是偶尔才发生。
可以看到,我在每次interrupt()语句后面,都向stdout输出一行。然后我在stdout里面找到了这两行输出,把它们和上面的输出放在一起看:
1304393163531 thread949-sleep true
1304393164531 No! thread949-sleep true
1304393163562 thread1128-sleep true
1304393164562 No! thread1128-sleep false可以看到,这两个interrupt()语句已经执行完了,而且是在stderr输出的1秒钟前。那么,为什么这两个sleep()没有被中断?P.S. 我在3台电脑上运行了这个程序很多次,3台都是Windows XP。上述情况只在其中两台发生,这两台都是酷睿双核 2.4GHz。在另一台电脑上没有发生,那台是赛扬 1.5GHz。它们的JDK版本都完全相同,都是1.6。
1、如果此时CPU马上切换,OS将CPU分配给刚刚启动的这个线程,让它休眠大概一秒,然后打印出No! false(为了简单,只列出只要信息),然后切换回来,t.interrupt(),然后打印出t.getName() + true,不过这种情况基本不可能发生,因为那个线程睡眠的时候OS不可能让CPU的闲置的2、如果此时CPU马上切换,OS将CPU分配给刚刚启动的这个线程,让它休眠大概一秒,此时CPU切换回来(上面那种不太可能的情况是:CPU在那不动,并不切换回来),执行t.interrupt(),有可以分两种情况:a、此时t启动的线程还在睡眠(1s还没过去),试图将一个正在睡眠的线程中断状态设置为true,那么t的中断状态就被清掉,也就是isInterrupted()会返回false,然后抛出一个InterruptedException,LZ的处理方法是return,所以打印出t.getName + false b、此时t启动的线程刚刚睡醒,在打印No!那些东西之前CPU回来,t.interrupt()把t的status设置为true,此时又可能因为CPU切换的关系,可能先打印t.getName() + true,也可能No! t.getName()+ true,反正可以随便想~~~如果t启动的线程睡醒后直接打印出执行打印No!的那句,那么因为t的中断状态还没被设定,所以打印No!+t.getName()+false,然后t.interrup()设定t的中断状态,再打印出t.getName() + true
大概就是这样,因为没有同步,多线程的结果是无法预测的,要考虑所以情况,而这个常常是很难做到的。
1304393163562 thread1128-sleep true
1304393164562 No! thread1128-sleep false前一个输出是在1秒钟以前,所以我觉得这肯定不是您说的情况b,而应该是情况a,所以thread1128-sleep应该被中断,抛出异常。可是为什么它没有?
1304393163531 thread949-sleep true
1304393163562 thread1128-sleep true
1304393164531 No! thread949-sleep true
1304393164562 No! thread1128-sleep falseInterrupt语句的时间是在sleep结束1秒之前!
现的我预期的结果是,程序不可能运行1分钟,因为这些sleep都会被中断。但是结果是,有几次果然运行了1分钟。所以结果和上次是一样的,确实有些sleep没有被中断。
for (int i = 1; i <= 10000; i++) {
Thread t = new Interrupt();
t.setName("thread" + i);
t.start();
Thread.sleep(1);
}
我加了一个Thread.sleep(1);问题就不会出现了。
System.out.println( System.currentTimeMillis() + " " +t.getName() + " " + t.isInterrupted() );谁能保证, interrupt之后,JVM执行的是ccer