为什么线程会放弃java suspend resume和Resume方法

博客访问: 2279918
博文数量: 569
博客积分: 13360
博客等级: 上将
技术积分: 5460
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Java
1. 线程的挂起和唤醒
&&&&& 挂起实际上是让线程进入“非可执行”状态下,在这个状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行;在线程挂起后,可以通过重新唤醒线程来使之恢复运行。挂起的原因可能是如下几种情况:&&&& (1)通过调用sleep()方法使线程进入休眠状态,线程在指定时间内不会运行。&&&& (2)通过调用join()方法使线程挂起,使自己等待另一个线程的结果,直到另一个线程执行完毕为止。&&&& (3)通过调用wait()方法使线程挂起,直到线程得到了notify()和notifyAll()消息,线程才会进入“可执行”状态。&&&& (4)使用suspend挂起线程后,可以通过resume方法唤醒线程。
虽然suspend和resume可以很方便地使线程挂起和唤醒,但由于使用这两个方法可能会造成死锁,因此,这两个方法被标识为
deprecated(抗议)标记,这表明在以后的jdk版本中这两个方法可能被删除,所以尽量不要使用这两个方法来操作线程。&&&&& 调用sleep()、yield()、suspend()的时候并没有被释放锁&&&&& 调用wait()的时候释放当前对象的锁
&&&&& wait()方法表示,放弃当前对资源的占有权,一直等到有线程通知,才会运行后面的代码。&&&&& notify()方法表示,当前的线程已经放弃对资源的占有,通知等待的线程来获得对资源的占有权,但是只有一个线程能够从wait状态中恢复,然后继续运行wait()后面的语句。&&&&& notifyAll()方法表示,当前的线程已经放弃对资源的占有,通知所有的等待线程从wait()方法后的语句开始运行。 2.等待和锁实现资源竞争&&&&& 等待机制与锁机制是密切关联的,对于需要竞争的资源,首先用synchronized确保这段代码只能一个线程执行,可以再设置一个标志位condition判断该资源是否准备好,如果没有,则该线程释放锁,自己进入等待状态,直到接收到notify,程序从wait处继续向下执行。synchronized(obj) {
  while(!condition) {
obj.wait();
  obj.doSomething();
}以上程序表示只有一个线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A释放该锁,进入wait()。&&&&& 在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:synchronized(obj) {
 condition = true;
 obj.notify();
}需要注意的是:  # 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {...} 代码段内。  # 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {...} 代码段内唤醒A。  # 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。  # 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。  # obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。  # 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。例1:单个线程对多个线程的唤醒&&&&& 假设只有一个Game对象,但有3个人要玩,由于只有一个游戏资源,必须必然依次玩。/**
&* 玩游戏的人.
&* @version V1.0 ,
&* @author xiahui
public class Player implements Runnable {
&&&&private final int id;
&&&&private Game game;
&&&&public Player(int id, Game game) {
&&&&&&&&this.id = id;
&&&&&&&&this.game = game;
&&&&public String toString() {
&&&&&&&&return "Athlete<" + id + ">";
&&&&public int hashCode() {
&&&&&&&&return new Integer(id).hashCode();
&&&&public void playGame() throws InterruptedException{
&&&&&&&&System.out.println(this.toString() + " ready!");
&&&&&&&&game.play(this);
&&&&public void run() {
&&&&&&&&try {
&&&&&&&&&&&&playGame();
&&&&&&&&} catch (InterruptedException e) {
&&&&&&&&&&&&System.out.println(this + " quit the game");
}游戏类,只实例化一个import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
&* 游戏类.
&* @version V1.0 ,
&* @author xiahui
public class Game implements Runnable {
&&&&private boolean start = false;
&&&&public void play(Player player) throws InterruptedException {
&&&&&&&&synchronized (this) {
&&&&&&&&&&&&while (!start)
&&&&&&&&&&&&&&&&wait();
&&&&&&&&&&&&if (start)
&&&&&&&&&&&&&&&&System.out.println(player + " have played!");
&&&&//通知所有玩家
&&&&public synchronized void beginStart() {
&&&&&&&&start = true;
&&&&&&&&notifyAll();
&&&&public void run() {
&&&&&&&&start = false;
&&&&&&&&System.out.println("Ready......");
&&&&&&&&System.out.println("Ready......");
&&&&&&&&System.out.println("game start");
&&&&&&&&beginStart();//通知所有玩家游戏准备好了
&&&&public static void main(String[] args) {
&&&&&&&&Set<Player> players = new HashSet<Player>();
&&&&&&&&//实例化一个游戏
&&&&&&&&Game game = new Game();
&&&&&&&&//实例化3个玩家
&&&&&&&&for (int i = 0; i < 3; i++)
&&&&&&&&&&&&players.add(new Player(i, game));
&&&&&&&&//启动3个玩家
&&&&&&&&Iterator<Player> iter = players.iterator();
&&&&&&&&while (iter.hasNext())
&&&&&&&&&&&&new Thread(iter.next()).start();
&&&&&&& Thread.sleep(100);
&&&&&&&&//游戏启动
&&&&&&&&new Thread(game).start();
}程序先启动玩家,三个玩家竞争玩游戏,但只能有一个进入play,其他二个等待,进入的玩家发现游戏未准备好,所以wait,等游戏准备好后,依次玩。运行结果Athlete ready!
Athlete ready!
Athlete ready!
Ready......
Ready......
game start
Athlete have played!
Athlete have played!
Athlete have played!3.一次唤醒一个线程&&&&& 一次唤醒所有玩家,但只有一个玩家能玩,不如一个一个唤醒将上面的代码修改如下&&& public void play(Player player) throws InterruptedException {
&&&&&&&&synchronized (this) {
&&&&&&&&&&&&while (!start)
&&&&&&&&&&&&&&&&wait();
&&&&&&&&&&&&if (start){
&&&&&&&&&&&&&&&&System.out.println(player + " have played!");
&&&&&&&&&&&&&&&&notify();//玩完后,通知下一个玩家来玩
&&&&&&&&&&&&}
&&&&//通知一个玩家
&&&&public synchronized void beginStart() {
&&&&&&&&start = true;
&&&&&&&&notify();
&&&&}4.suspend挂起&&&&& 该方法已不建议使用,例子如下例2:suspend方法进行挂起和唤醒
&* suspend方法进行挂起和唤醒.
&* @version V1.0 ,
&* @author xiahui
public class SuspendThread implements Runnable{
&&&&public void run() {
&&&&&&&&try {
&&&&&&&&&&&&Thread.sleep(10);
&&&&&&&&} catch (Exception e) {
&&&&&&&&&&&&System.out.println(e);
&&&&&&&&for (int i = 0; i <= 1; i
&&&&&&&&&&&&System.out.println(Thread.currentThread().getName()
&&&&public static void main(String args[]) throws Exception {
&&&&&&&&Thread th1 = new Thread(new SuspendThread(),"thread1");
&&&&&&&&Thread th2 = new Thread(new SuspendThread(),"thread2");
&&&&&&&&System.out.println("Starting "
th1.getName()
&&&&&&&&th1.start();
&&&&&&&&System.out.println("Suspending "
th1.getName()
&&&&&&&&//Suspend the thread.
&&&&&&&&th1.suspend();
&&&&&&&&th2.start();
&&&&&&&&th2.join();
&&&&&&&&// Resume the thread.
&&&&&&&&th1.resume();
Starting thread1...
Suspending thread1...
&&&&& 如果注释掉//th2.join();则thread2运行后,主线程会直接执行thread1的resume,运行结果可能会是
Starting thread1...
Suspending thread1...
参考文献<font color="#.Java多线程设计模式:了解wait/notify机制. .cn/wsjavtec/335/8580335.shtml2.Java中使用wait()与notify()实现线程间协作. /Programming/Java/15.htm
阅读(19678) | 评论(0) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。怎样干净又安全的终止线程_百度知道Java多线程之线程的挂起与恢复(suspend方法与resume方法)_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Java多线程之线程的挂起与恢复(suspend方法与resume方法)
来源:Linux社区&
作者:hapjin
本文讨论Java多线程中,使用 thread.suspend()方法暂停线程,使用 thread.resume()恢复暂停的线程的特点。
先介绍二个关于线程的基本知识:
①线程的执行体是run()方法里面的每一条语句,main线程执行的则是main()方法里面的语句。
②Thread.sleep()方法 使当前正在执行的线程睡眠。
二,suspend()方法
①当某个线程的suspend()方法被调用时,该线程会被挂起。如果该线程占有了锁,则它不会释放锁。即,线程在挂起的状态下还持有锁。
②suspend()已经是一个过时的方法了。
来分析一段代码:
public class MyThread extends Thread {
& & private long i = 0;
& & public long getI() {& & & && & }
& & public void setI(long i) {& & & & this.i =& & }
& & @Override& & public void run() {& & & & while (true) {& & & & & & i++;& & & & & & System.out.println(i);//同步方法& & & & }& & }
------------------------------------------------
&1 public class Run { 2 3& &
public static void main(String[] args) {4 5& & & &
try {6& & & & & &
MyThread thread = new MyThread();7& & & & & &
thread.start();//启动一个线程'thread'8 Thread.sleep(1000);//使当前线程(main线程)睡眠9& & & & & &
thread.suspend();//挂起线程'thread'10& & & & & &
System.out.println("main end!");11& & & &
} catch (InterruptedException e) {12 & & & & & & e.printStackTrace();13 & & & & }14 & & }15 16 }
在第8行,睡眠的线程是main线程。这样第7行启动的线程'thread'就有机会获得CPU执行,于是:MyThread类的run()方法中的代码就执行了。
当main线程睡眠了1秒钟并重新获得了CPU执行时,执行到第9行。
在第9行,让 第7行中启动的线程 suspend(挂起)。
于是,'thread'线程就不会再打印i的值了。然后,main线程继续执行到第10行,准备打印"main end!"
但是,由于System.out.println(...),它是一个同步方法,PrintOut的println(Object o)的源代码如下:
* Prints an Object and then terminate the line.
This method calls
* at first String.valueOf(x) to get the printed object's string value,
* then behaves as
* though it invokes &code&{@link #print(String)}&/code& and then
* &code&{@link #println()}&/code&.
* @param x
The &code&Object&/code& to be printed.
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
newLine();
可以看出,在第12行,需要先获得当前PrintOut对象的锁。
而由于此时,MyThread类的线程'thread'是挂起的。它的run()方法里面也有打印语句。因此,它占有的PrintOut的对象锁没有释放。
从而导致main线程无法执行Run.java中的第10行,打印输出语句。
注意 PrintOut是System类中的一个静态属性,System类中只有唯一的一个PrintOut对象,System类中相关源代码如下:
* The "standard" output stream. This stream is already
* open and ready to accept output data. Typically this stream
* corresponds to display output or another output destination
* specified by the host environment or user.
* For simple stand-alone Java applications, a typical way to write
* a line of output data is:
* &blockquote&&pre&
System.out.println(data)
* &/pre&&/blockquote&
* See the &code&println&/code& methods in class &code&PrintStream&/code&.
public final static PrintStream out = null;&
三,resume()方法
该方法很功能很简单,就是恢复 因suspend()方法挂起的线程,使之重新能够获得CPU执行。
本文永久更新链接地址:
相关资讯 & & &
& (昨 21:21)
& (昨 20:58)
& (昨 21:20)
& (08月19日)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款怎样干净又安全的终止线程_百度知道}

我要回帖

更多关于 线程suspend 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信