Java暂停/挂起线程(suspend())和恢复线程(resume())
暂停线程意味着此线程还可以恢复运行。在 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())相关推荐
- 暂停线程suspend()和恢复线程resume()
1.使用suspend()方法暂停线程(挂起) : 运行->阻塞 2.使用resume()方法恢复线程 : 阻塞->就绪 suspend() 和 resume() 被用在等待另一个线程产生 ...
- java 线程resume_Java暂停/挂起线程(suspend())和恢复线程(resume())
暂停线程意味着此线程还可以恢复运行.在 Java 多线程中,可以使用 suspend() 方法暂停线程,使用 resume() 方法恢复线程的执行. suspend() 与 resume() 方法 本 ...
- 线程的挂起(suspend)和继续执行(resume)是什么情况?
前言 本文隶属于专栏<100个问题搞定Java并发>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定Java并发 ...
- java 中有几种方法可以实现一个线程?用什么关键字修饰同步方法 ? stop() 和 suspend() 方 法为何不推荐使用?
60 . java 中有几种方法可以实现一个线程?用什么关键字修饰同步方法 ? stop() 和 suspend() 方 法为何不推荐使用? 答: 有两种实现方法,分别是继承 Thread类与实现Ru ...
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
答: 1.有两种实现方法,分别是继承Thread类与实现Runnable接口 继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了. 2.用synchronized关 ...
- Java并发 正确终止与恢复线程
为什么80%的码农都做不了架构师?>>> 前面提到了stop().suspend()等方法在终止与恢复线程的弊端,那么问题来了,应该如何正确终止与恢复线程呢?这里可以使用两种方 ...
- Java中有几种方法可以实现一个线程??用什么关键字修饰同步方法??stop()和suspend()方法为什么不推荐使用??
1. Java中有几种方法可以实现一个线程?? 两种,分别是继承thread类和实现Runnable类接口. 第一种: new Thread(){}.start();这表示调用Thread子类对象的r ...
- 易语言创建线程挂起线程恢复线程销毁线程
线程创建CreateThread,线程挂起SuspendThread,线程恢复ResumeThread,线程销毁TerminateThread,都是kernel32的命令,我们自己封装这些线程的命令, ...
- (58)模拟线程切换——添加挂起、恢复线程功能
一.回顾 我们在上一篇博客分析了模拟线程切换的源码. <模拟线程切换> 我们着重分析了 Scheduling 和 SwitchContext 这两个函数,对线程切换的过程有了新的认识: 线 ...
最新文章
- 5行Python提取海量新闻网站内容
- 连接一切:自媒体的未来是什么??
- ASP.NET程序中常用代码汇总(四)
- iscsi没有可用于使用快速连接登陆的目标_iSCSI的基本架构及操作简介
- P4011 孤岛营救问题
- 生产环境使用HBase,你必须知道的最佳实践
- django 项目中遇到的问题(持续更新中)
- eclipse web项目页面显示404_404 Not Found错误页面是什么?
- 成员变量和方法的理解
- UML常用图--类图,用例图,序列图(时序图),协作图(通信图),状态图,活动图
- 邮递员问题java实现_中国邮递员问题算法.PPT
- 告诉你60个经典的电脑使用技巧
- Python:学习成绩管理系统
- html5 移动端 开发工具,H5推荐:最好用的五大移动应用开发工具
- 运放的选取标准和规则
- PowerShell重名名
- 1、esp32(arduino)接入阿里云MQTT及数据处理
- 怎么自学软件测试?自学软件测试需要多久?--请看我是如何走过来的!
- 如何下载沧州市卫星地图高清版大图
- 浅析巴西恶意软件进化史