暂停线程意味着此线程还可以恢复运行。在 Java 多线程中,可以使用 suspend() 方法暂停线程,使用 resume() 方法恢复线程的执行。

suspend() 与 resume() 方法

本节通过一个案例来介绍 suspend() 与 resume() 方法的用法。首先来看一下案例中使用到的 MyThread21 线程,代码如下所示。

package ch14;
public class MyThread21 extends Thread
{private long i=0;public long getI(){return i;}public void setI(long i){this.i=i;}@Overridepublic void run(){while(true){i++;}}
}

MyThread21 线程中有一个成员 i,其中 setI() 方法和 getI() 方法分别用于设置和获取 i 的值,run() 方法则是一个从i开始递增的死循环。

下面编写主线程的代码,具体如下所示。

package ch14;
public class Test25
{public static void main(String[] args){try{MyThread21 thread=new MyThread21();thread.start();Thread.sleep(5000);//A段thread.suspend();System.out.println("A= "+System.currentTimeMillis()+" i= "+thread.getI());Thread.sleep(5000);System.out.println("A= "+System.currentTimeMillis()+" i= "+thread.getI());//B段thread.resume();Thread.sleep(5000);//C段thread.suspend();System.out.println("B= "+System.currentTimeMillis()+" i= "+thread.getI());Thread.sleep(5000);System.out.println("B= "+System.currentTimeMillis()+" i= "+thread.getI());}catch(InterruptedException e){e.printStackTrace();}}
}

最终运行结果如下所示。

A= 1540978346179 i= 2680986095
A= 1540978351179 i= 2680986095
B= 1540978356179 i= 5348657508
B= 1540978361179 i= 5348657508

从输出结果的时间来看,调用 suspend() 方法确实可以暂停线程,而在调用 resume() 方法后线程恢复运行状态。

独占问题

在使用 suspend() 方法与 resume() 方法时,如果使用不当极易造成公共的同步对象被独占,从而使得其他线程无法访问公共同步对象。

例 2

下面通过一个案例来演示这种情况。如下所示是案例中使用的公共对象的代码。

package ch14;
public class SynchronizedObject1
{synchronized public void printString(){System.out.println("begin");if (Thread.currentThread().getName().equals("a")){System.out.println("a线程永远 suspend了!");Thread.currentThread().suspend();}System.out.println("end");}
}

SynchronizedObject1 类在 printString() 方法开始时输出“begin”,在该方法结束时输出“end”,方法体中的if判断如果当前线程的名称是 a 则调用 suspend() 方法暂停线程。

接下来编写主线程代码,在主线程中创建一个 SynchronizedObject1 类对象并在线程中调用 printString() 方法,具体代码如下所示。

package ch14;
public class Test26
{public static void main(String[] args){try{final SynchronizedObject1 object=new SynchronizedObject1();Thread thread1=new Thread(){@Overridepublic void run(){object.printString();}};thread1.setName("a");thread1.start();Thread.sleep(1000);Thread thread2=new Thread(){@Overridepublic void run(){System.out.println("thread2启动了,但进入不了printString()方法!所以只会打印1个begin!");System.out.println("因为printString()方法被a线程锁定并且永远暂停了!");object.printString();}};thread2.start();}catch(InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}
}

上述代码比较简单这里就不再解释,运行后的结果如下所示。从中可以看到由于线程被永久暂停,所以只会输出一个 begin。

begin
a线程永远 suspend了!
thread2启动了,但进入不了printString()方法!所以只会打印1个begin!
因为printString()方法被a线程锁定并且永远暂停了!

例 3

还有另外一种独占锁的情况也要格外注意,稍有不慎就会掉进“坑”里。创建测试用的 MyThread22 线程,具体代码如下:

package ch14;
public class MyThread22 extends Thread
{private long i=0;@Overridepublic void run(){while (true){i++;}}
}

再来看主线程的代码,如下所示。

package ch14;
public class Test27
{public static void main(String[] args){try{MyThread22 thread=new MyThread22();thread.start();Thread.sleep(1000);thread.suspend();System.out.println("main end!");}catch(InterruptedException e){e.printStackTrace();}}
}

程序执行后将看到预料不到的结果,如下所示。

main end!如果将 MyThread22 线程类的代码更改如下:
package ch14;
public class MyThread22 extends Thread
{   private long i=0; @Override public void run(){ while(true){ i++; System.out.println(i); } }
}

再次运行程序,控制台将不打印 main end,运行结果如下所示。

......
130862
130863
130864
130865
130866
130867

出现这种情况的原因是,当程序运行到 println() 方法内部停止时,同步锁未被释放。这导致当前 PrintStream 对象的 println() 方法一直呈“暂停”状态,并且“锁未释放”,而 main() 方法中的代码“System.out. println(Mmain end!'1);”迟迟不能执行打印。

提示:虽然 suspend() 方法是过期作废的方法,但还是有必要研究它过期作废的原因,这是很有意义的。

不同步问题

在使用 suspend() 方法与 resume() 方法时也容易出现因为线程的暂停而导致数据不同步的情况。

例 4

下面通过一个案例来演示这种情况。如下所示是案例中使用的公共对象的代码。

package ch14;
public class MyObject
{private String username="1";private String password="11";public void setValue(String u,String p){this.username=u;if(Thread.currentThread().getName().equals("a")){System.out.println("停止a线程!");Thread.currentThread().suspend();}this.password=p;}public void printUsernamePassword(){System.out.println(username+" "+password);}
}

如上述代码所示,MyObject 类的 setValue() 方法会在线程名称是 a 时执行停止线程操作。 如下所示是主线程代码。

package ch14;
public class Test28
{public static void main(String[] args) throws InterruptedException{final MyObject myobject=new MyObject();Thread thread1=new Thread(){public void run(){myobject.setValue("a","aa");};};thread1.setName("a");thread1.start();Thread.sleep(500);Thread thread2=new Thread(){public void run(){myobject.printUsernamePassword();};};thread2.start();}
}

程序运行结果如下所示。

停止a线程!
a 11

Java暂停/挂起线程(suspend())和恢复线程(resume())相关推荐

  1. 暂停线程suspend()和恢复线程resume()

    1.使用suspend()方法暂停线程(挂起) : 运行->阻塞 2.使用resume()方法恢复线程 : 阻塞->就绪 suspend() 和 resume() 被用在等待另一个线程产生 ...

  2. java 线程resume_Java暂停/挂起线程(suspend())和恢复线程(resume())

    暂停线程意味着此线程还可以恢复运行.在 Java 多线程中,可以使用 suspend() 方法暂停线程,使用 resume() 方法恢复线程的执行. suspend() 与 resume() 方法 本 ...

  3. 线程的挂起(suspend)和继续执行(resume)是什么情况?

    前言 本文隶属于专栏<100个问题搞定Java并发>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定Java并发 ...

  4. java 中有几种方法可以实现一个线程?用什么关键字修饰同步方法 ? stop() 和 suspend() 方 法为何不推荐使用?

    60 . java 中有几种方法可以实现一个线程?用什么关键字修饰同步方法 ? stop() 和 suspend() 方 法为何不推荐使用? 答: 有两种实现方法,分别是继承 Thread类与实现Ru ...

  5. java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?

    答: 1.有两种实现方法,分别是继承Thread类与实现Runnable接口 继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了. 2.用synchronized关 ...

  6. Java并发 正确终止与恢复线程

    为什么80%的码农都做不了架构师?>>>    前面提到了stop().suspend()等方法在终止与恢复线程的弊端,那么问题来了,应该如何正确终止与恢复线程呢?这里可以使用两种方 ...

  7. Java中有几种方法可以实现一个线程??用什么关键字修饰同步方法??stop()和suspend()方法为什么不推荐使用??

    1. Java中有几种方法可以实现一个线程?? 两种,分别是继承thread类和实现Runnable类接口. 第一种: new Thread(){}.start();这表示调用Thread子类对象的r ...

  8. 易语言创建线程挂起线程恢复线程销毁线程

    线程创建CreateThread,线程挂起SuspendThread,线程恢复ResumeThread,线程销毁TerminateThread,都是kernel32的命令,我们自己封装这些线程的命令, ...

  9. (58)模拟线程切换——添加挂起、恢复线程功能

    一.回顾 我们在上一篇博客分析了模拟线程切换的源码. <模拟线程切换> 我们着重分析了 Scheduling 和 SwitchContext 这两个函数,对线程切换的过程有了新的认识: 线 ...

最新文章

  1. 5行Python提取海量新闻网站内容
  2. 连接一切:自媒体的未来是什么??
  3. ASP.NET程序中常用代码汇总(四)
  4. iscsi没有可用于使用快速连接登陆的目标_iSCSI的基本架构及操作简介
  5. P4011 孤岛营救问题
  6. 生产环境使用HBase,你必须知道的最佳实践
  7. django 项目中遇到的问题(持续更新中)
  8. eclipse web项目页面显示404_404 Not Found错误页面是什么?
  9. 成员变量和方法的理解
  10. UML常用图--类图,用例图,序列图(时序图),协作图(通信图),状态图,活动图
  11. 邮递员问题java实现_中国邮递员问题算法.PPT
  12. 告诉你60个经典的电脑使用技巧
  13. Python:学习成绩管理系统
  14. html5 移动端 开发工具,H5推荐:最好用的五大移动应用开发工具
  15. 运放的选取标准和规则
  16. PowerShell重名名
  17. 1、esp32(arduino)接入阿里云MQTT及数据处理
  18. 怎么自学软件测试?自学软件测试需要多久?--请看我是如何走过来的!
  19. 如何下载沧州市卫星地图高清版大图
  20. 浅析巴西恶意软件进化史

热门文章

  1. 通用试验体系支撑平台下的反射内存网通信组件开发
  2. mos管选型注重的必备参数,值得收藏!
  3. proteus仿真arduino控制两位数码管
  4. 深入理解Linux虚拟内存管理(一)
  5. 2008年世界顶级杀毒软件排名
  6. CIDR 计算网络地址、子网掩码、广播地址
  7. 在 Ubuntu18.04 中为fctix小企鹅增加五笔输入法
  8. Matlab在命定行窗口输出提示语:disp函数
  9. 电气simulink常用模块_建筑电气制图图形符号之二,火灾自动报警符号,赶快收藏吧...
  10. smart 3D 中的block merge(空三合并)功能详细介绍