使用 suspend 和 resume 暂停和恢复线程
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 暂停和恢复线程的更多相关文章
- Java中的线程Thread方法之---suspend()和resume()
前篇说到了Thread中的join方法,这一篇我们就来介绍一下suspend()和resume()方法,从字面意义上可以了解到这两个方法是一对的,suspend()方法就是将一个线程挂起(暂停),re ...
- Android中的java层的线程暂停和恢复实现
/** * 基础线程对象. * * @author jevan * @version (1.0 at 2013-6-17) * @version (1.1 at 2013-7-2) 增加on ...
- C# 线程的暂停和恢复的 实现
我们可以通过ManualResetEvent类来实现. 声明, 初始化时不执行 private static ManualResetEvent _eventWorkList = new ManualR ...
- 利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复(转)
利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复 打印过程可能很长,这时候有可能需要暂停下来做一些事情,然后回来继续接着打印 打印过程中有2个线程:一个是程序运行的主线程, ...
- ManualResetEvent实现线程的暂停与恢复
背景 前些天遇到一个需求,在没有第三方源码的情况下,刷新一个第三方UI,并且拦截到其ajax请求的返回结果.当结果为AVALIABLE的时候,停止刷新并语音提示,否则继续刷新. 分析这个需求,发现需要 ...
- C# Thread挂起线程和恢复线程
前言 众所周知,Thread类中的挂起线程和恢复线程微软已标记过时,因为可能会造成问题 Resume() 恢复当前线程 已过时. Resumes a thread that has been ...
- JAVA多线程suspend()、resume()和wait()、notify()的区别
suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的 resume() 被调用,才能使得线程重新进入可执行状态.典型 ...
- Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
Thread.stop, Thread.suspend, Thread.resume被标记为废弃的方法.在查看JDK的文档时,提到了下面的参考文章,先是英文版,接着是中文翻译. Why is Thre ...
- Linux的系统suspend和resume
参考: www.wowotech.net/linux_kenrel/suspend_and_resume.htmlwww.wowotech.net/linux_kenrel/pm_interface. ...
随机推荐
- thinkphp 4.8 漏洞测试
首先要部署环境 这里利用docker的方便部署性,来直接找个现成的 git clone https://github.com/vulnspy/thinkphp-5.1.29.git 下载安装后, ...
- 用Python获取黄石市近7天天气预报
首先,我们打开中国天气网,找到黄石市近7天天气的网页.http://www.weather.com.cn/weather/101200601.shtml 然后按F12开始分析网页结构,找到各个标签,并 ...
- JS-实现横向手风琴
横向手风琴-- 鼠标悬浮某一张图片,图片显示,其他图片影藏. <div class="content"> <ul> <li class="c ...
- vue使用sass报Modele build failed: TypeError: this.getResolve is not a function at Object.loader...
项目中使用sass报错,之前一直使用同样的安装方式 cnpm install sass-loader node-sass -D,正常使用没问题,没想到这次同样的方式却报错了,网上查的原因是sass-l ...
- 10.SpringMVC注解式开发-处理器方法的参数
1.逐个参数接收 只要保证请求参数名与该请求处理方法的参数名相同即可 // 请求参数名 与该处理器中的请求方法的参数名相同 ,即可接收前台传递过来的参数 public ModelAndView met ...
- Python学习记录6-list、tuple、dict、set复习
数据类型在一门语言中是非常重要的,所以选择再次学习一下加深记忆.本次主要参考了大神廖雪峰的官方网站,非常感谢大神,讲的很清晰,收获很大. 标准数据类型 Number(数字) String(字符串) L ...
- Djnago模板与标签
1.模版系统 基本语法 {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 在Django的模板语言中按此语法使用:{{ 变量名 }}. python基础的基本数据类型可以通 ...
- Redis5.0.3单机版安装
一.创建redis源码包存放目录 cd /usr/local/ mkdir redis 二.进入创建的目录,下载最新版Redis yum -y install wget wget http://dow ...
- 如何在SpringBoot的 过滤器之中注入Bean对象
我建立一个全局拦截器,此拦截器主要用于拦截APP用户登录和请求API时候,必须加密,我把它命名为SecurityFilter,它继承了Filter,web应用启动的顺序是:listener->f ...
- Spring入门篇——第4章 Spring Bean装配(下)
第4章 Spring Bean装配(下) 介绍Bean的注解实现,Autowired注解说明,基于java的容器注解说明,以及Spring对JSR支持的说明 4-1 Spring Bean装配之Bea ...