suspend 和 resume 的使用

在 Thread 类中有这样两个方法:suspend 和 resume,这两个方法是成对出现的。

  • suspend() 方法的作用是将一个线程挂起(暂停),
  • resume() 方法的作用则是将一个挂起的线程重新开始并继续向下运行。

通过一个例子来看一下这两个方法的使用:

public class SuspendThread {

    public static void main(String[] args) {
SimpleDateFormat f = new SimpleDateFormat("HH:mm:ss"); try {
MyThread2 t = new MyThread2();
t.start();
Thread.sleep(1000); //暂停线程
t.suspend();
System.out.println("暂停线程:" +
f.format(System.currentTimeMillis()) +
", num = " + t.getNum());
Thread.sleep(5000);
System.out.println("暂停线程5秒后:" +
f.format(System.currentTimeMillis()) +
", num = " + t.getNum()); //继续线程
t.resume();
System.out.println("--恢复线程--");
Thread.sleep(5000);
System.out.println("--恢复线程5秒后--"); //再次暂停线程
t.suspend();
System.out.println("再次暂停:" +
f.format(System.currentTimeMillis()) +
", num = " + t.getNum());
Thread.sleep(5000);
System.out.println("再次暂停5秒后:" +
f.format(System.currentTimeMillis()) +
", num = " + t.getNum()); } catch (Exception e) {
e.printStackTrace();
}
} } class MyThread2 extends Thread{
private long num = 0; public void setNum(long num) {
this.num = num;
} public long getNum(){
return num;
} @Override
public void run() {
while(true){
num++;
}
} }

输出结果:

暂停线程:15:27:21, num = 612874824
暂停线程5秒后:15:27:26, num = 612874824
--恢复线程--
--恢复线程5秒后--
再次暂停:15:27:31, num = 3663392709
再次暂停5秒后:15:27:36, num = 3663392709

从输出结果打印的时间上看来,线程确实被暂停了,而且还能恢复继续运行。

为什么弃用?

虽然现在已经成功的暂停和恢复了线程,但是我们会发现 suspend 和 resume 早已被标注为了废弃方法,并且不推荐使用了。

不释放锁

这是因为 suspend 方法不会释放锁,而如果调用了 suspend 方法的目标线程在挂起时对某一重要的系统资源持有锁,那么在目标线程重新开始之前其他任何线程都无法访问该资源。

public class SynchronizedObject {

    public static void main(String[] args) throws InterruptedException {

        final SynchronizedObject object = new SynchronizedObject();

        Thread thread1 = new MyThread3(object);
Thread thread2 = new MyThread3(object); thread1.setName("thread1");
thread1.start(); Thread.sleep(1000); thread2.setName("thread2");
thread2.start(); } //使用synchronized实现锁功能
synchronized public void printString(){
String threadName = Thread.currentThread().getName(); System.out.println(threadName + " - begin");
if(threadName.equals("thread1")) {
System.out.println("thread1 - suspend");
Thread.currentThread().suspend();
}
System.out.println(threadName + " - end");
} static class MyThread3 extends Thread {
SynchronizedObject obj; public MyThread3(SynchronizedObject obj) {
this.obj = obj;
} @Override
public void run() {
obj.printString();
}
}
}

输出结果:

thread1 - begin
thread1 - suspend

从打印的结果来看,虽然 thread2 被启动了,但是并没有进入它的 printString() 方法,这便是因为 printString 方法已经被 thread1 线程锁定并暂定了,导致其他线程无法访问公共代码块。

不同步

使用 suspend 和 resume 方法也容易出现因为线程的暂停而导致数据不同步的问题。

public class TestObject {

    public static void main(String[] args) throws InterruptedException {
final UserObject obj = new UserObject();
Thread thread1 = new Thread() {
public void run() {
obj.setValue("lisi", "30");
};
}; thread1.setName("thread1");
thread1.start();
thread1.sleep(500); Thread thread2 = new Thread(){
public void run() {
obj.printValue();
};
}; thread2.start(); } static class UserObject {
private String name = "zhangsan";
private String age = "18"; public void setValue(String name, String age) {
this.name = name;
if(Thread.currentThread().getName().equals("thread1")){
System.out.println("暂停 thread1");
Thread.currentThread().suspend();
}
this.age = age;
} private void printValue(){
System.out.println(name + " : " + age);
}
} }

输出结果:

暂停 thread1
lisi : 18

程序运行的结果出现了不同步的情况,所以不再建议使用 suspend 和 resume 方法了。

使用 suspend 和 resume 暂停和恢复线程的更多相关文章

  1. Java中的线程Thread方法之---suspend()和resume()

    前篇说到了Thread中的join方法,这一篇我们就来介绍一下suspend()和resume()方法,从字面意义上可以了解到这两个方法是一对的,suspend()方法就是将一个线程挂起(暂停),re ...

  2. Android中的java层的线程暂停和恢复实现

    /**  * 基础线程对象.  *  * @author jevan  * @version (1.0 at 2013-6-17)  * @version (1.1 at 2013-7-2) 增加on ...

  3. C# 线程的暂停和恢复的 实现

    我们可以通过ManualResetEvent类来实现. 声明, 初始化时不执行 private static ManualResetEvent _eventWorkList = new ManualR ...

  4. 利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复(转)

    利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复 打印过程可能很长,这时候有可能需要暂停下来做一些事情,然后回来继续接着打印 打印过程中有2个线程:一个是程序运行的主线程, ...

  5. ManualResetEvent实现线程的暂停与恢复

    背景 前些天遇到一个需求,在没有第三方源码的情况下,刷新一个第三方UI,并且拦截到其ajax请求的返回结果.当结果为AVALIABLE的时候,停止刷新并语音提示,否则继续刷新. 分析这个需求,发现需要 ...

  6. C# Thread挂起线程和恢复线程

    前言 众所周知,Thread类中的挂起线程和恢复线程微软已标记过时,因为可能会造成问题   Resume()   恢复当前线程 已过时. Resumes a thread that has been ...

  7. JAVA多线程suspend()、resume()和wait()、notify()的区别

    suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的 resume() 被调用,才能使得线程重新进入可执行状态.典型 ...

  8. Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?

    Thread.stop, Thread.suspend, Thread.resume被标记为废弃的方法.在查看JDK的文档时,提到了下面的参考文章,先是英文版,接着是中文翻译. Why is Thre ...

  9. Linux的系统suspend和resume

    参考: www.wowotech.net/linux_kenrel/suspend_and_resume.htmlwww.wowotech.net/linux_kenrel/pm_interface. ...

随机推荐

  1. [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam

    [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam https://blog.csdn.net/u010089444/article/details/76 ...

  2. 主流RPC框架详解,以及与SOA、REST的区别

    什么是RPC RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 简言之,RPC使 ...

  3. .net工作流引擎ccflow集成并增加自定义功能

    一.为什么需要自定义扩展 1.第三方类库已满足大部分需求,剩下的根据具体业务需求抽象成公共功能进行扩展 2.第三方呈现的web页面与原类库耦合度较高,希望在原页面上扩展而不影响原来的功能 3.在完全不 ...

  4. Django form表单修改数据

    form: #!/usr/bin/env python #coding:utf8 from django.forms import Form,ModelForm import models class ...

  5. CentOS下更改yum源

    centos下下载工具为yum,对应的源在/etc/yum.repos.d/CentOS-Base.repo文件下,修改其URI中前面的网络地址即可

  6. WebRtc的一些基本概念

    GCC:Google Congestion Control,谷歌提出的拥塞控制算法 REMB:Receiver Estimated Maximum Bitrate,  接收端最大接收码率估测,接收端会 ...

  7. Windows 7 [Web应用程序项目***已配置为使用IIS。无法访问IIS元数据库,您没有足够的特权访问计算机上的IIS网站]

    如下所示,我最近也遇到这个类似的错误(Win7 + IIS7.0),最后如下图解决 系统用户权限问题, 通过管理员运行 即可正常使用.

  8. Python模块之目录

     1.加密算法有关 hmac模块 hashlib模块 2.进程有关 multiprocessing模块 3.线程有关 threading模块 4.协程有关 asyncio模块 5.系统命令调用 sub ...

  9. MFC 树形控件

    Tree Control属性:Has Buttons.Has Lines.Lines At Root这三个设为True 常用的事件:SelectChanged() ico图片放到项目的res文件夹中( ...

  10. 02 CSS和DIV对界面优化

    01 网站首页的优化 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...