您的位置:首页 > 编程语言 > Java开发

java多线程中断学习

2009-05-07 09:07 288 查看
来至《java多线程设计模式》

1.wait

   (1)调用wait方法必须先获得对象实例的锁;

   (2)可以再synchronized方法中,或synchronized块中或两者调用的别的方法中;

   (3)执行wait方法的线程会进入obj的wait set里面,进入之后就已经释放obj的锁;

   (4)被notify或notifyAll所唤醒的线程会前进到wait的下一个语句。

2.nofify和notifyAll

  (1)从obj的wait set中唤醒一个或所有线程(它们试图去获取obj的锁),但是唤醒它(们)之后,该线程仍未释放该锁

  (2)wait,notify,notifyAll为object类的方法,对实例的wait set进行操作。

3.sleep

  (1)为线程类方法,让线程进入阻塞状态,得不到CPU时间,时间一过重新进入可执行状态。但sleep方法不会释放对象的锁。

  (2)只能控制当前正在运行的线程。

4.yield

  (1)暂停当前正在执行的线程对象,并执行其他线程,让当前运行的线程回到可运行状态,并允许具有相同优先级的其他线程获得运行机会。

  (2)但它可能未让步而重新被调度程序选中。

5.join

  (1)让一个线程B加入到另一个线程A的尾部。

  (2)A执行完毕之前,B不能工作。

 

二、调用interrupt()的影响:

1.对sleep

   任何线程在任何时刻都可以调用其他线程的interrupt方法,被interrupt后放弃暂停状态,抛出异常。

2.对wait

  若obj已经在wait set中,interrupt方法会使线程重新获得锁再抛出异常,若未能获得锁定,则无法抛出异常。

  执行interrupt时无需获得对该线程的锁定。

3.join

  调用joion方法,无需获得锁定,马上跳到catch块里。

 

三、调用interrupt方法不一定会抛出interruptException:

   (1)若调用时,不是在执行sleep/wait/join则不会抛出异常,只是改变中断状态;

   (2)若调用时,是在执行sleep/wait/join则抛出异常。

 

//  作业
private void doWork() throws InterruptedException {
counter++;
System.out.println("doWork: counter = " + counter);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}


以上若调用interrupt则无法中断。

System.out.println("main: shutdownRequest");
t.shutdownRequest();


必须如下:

// 作业
private void doWork() throws InterruptedException {
counter++;
System.out.println("doWork: counter = " + counter);
Thread.sleep(500);
}


则可以正常终止。

在调用doWork的地方进行捕获:

// 动作
public void run() {
try {
while (!isInterrupted()) {
doWork();
}
} catch (InterruptedException e) {
} finally {
doShutdown();
}
}


// 终止请求
public void shutdownRequest() {
interrupt();
}


 


上面那个捕获异常之后没有处理,所以在run里面无法捕获,无法执行doShutdown方法来停止。

 

对比:

public synchronized Request getRequest() throws InterruptedException {
while (queue.size() <= 0) {
wait();
}
return (Request)queue.removeFirst();
}


这里抛出异常,同时在调用的地方进行捕获,并且退出run

public void run() {
try {
for (int i = 0; i < 10000; i++) {
Request request = new Request("No." + i);
System.out.println(Thread.currentThread().getName() + " requests " + request);
requestQueue.putRequest(request);
Thread.sleep(random.nextInt(1000));
}
} catch (InterruptedException e) {
}
}


调用时,是直接interrupt:

//呼叫interrupt方法
System.out.println("***** calling interrupt *****");
alice.interrupt();
bobby.interrupt();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: