使用 suspend 和 resume 暂停和恢复线程
2024-09-01 15:17:49
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 方法了。
最新文章
- CSS基础知识汇总
- NYOJ 478
- 深入理解JavaScript系列:为什么03-0.2不等于0.1
- Java中测试异常的多种方式
- spring之依赖注入
- H5图片裁剪升级版(手机版)
- Linux 下网络性能优化方法简析
- 在vs中跑动ransac
- ThreadLocal学习
- python2.+进化至python3.+ 语法变动差异(不定期更新)
- Database name和SID
- javascritp第十课:面向对象
- g4e基础篇#3 Git安装与配置
- [Swift]LeetCode79. 单词搜索 | Word Search
- CentOS7+CDH5.14.0安装全流程记录,图文详解全程实测-6CM安装前环境检查
- HDU - 1166 - 敌兵布阵 线段树的单点修改,区间求和
- laravel 获取当前月,当前星期,当天起始时间方法
- 【iCore4 双核心板_FPGA】例程十四:基于I2C的ARM与FPGA通信实验
- Oracle Data Integrator学习资料
- (转载)-关于sg函数的理解