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

2024-06-10 16:08

本文主要是介绍Java中的线程Thread方法之---suspend()和resume(),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前篇说到了Thread中的join方法,这一篇我们就来介绍一下suspend()和resume()方法,从字面意义上可以了解到这两个方法是一对的,suspend()方法就是将一个线程挂起(暂停),resume()方法就是将一个挂起线程复活继续执行。首先看一个例子:

package cn.edu.ahui;
import java.util.Iterator;  
import java.util.Map;  
import java.util.Map.Entry;  
import java.util.Set;  /** * @author weijiang204321 *说明: *调用了suspend方法,将t0线程挂起,但是出现的问题是,t0.suspend方法之后的代码不执行了,搞了半天终于知道为什么了, *因为在t0里面使用了System.out.println方法了,查看println方法的源代码发现他是个同步的方法,加锁了,这个锁是哪个呢? *对就是PrintStream,在Main中的printCurrentAliveThread方法中用到了System.out.println方法,打断点才知道 *搞了半天阻塞在这里了,因为我们知道suspend方法是不释放锁的,所以导致会阻塞在println方法中,但是有一个前提是t0线程和main线程 *的println方法中拿到的是同一个锁,这时候在看一下System.out变量时一个static PrintStream,这时候就明了了,因为是static *所以对象是相同的,这两个线程拿到的System.out是同一个对象,所以这两个线程也是拿到的是相同的锁的。 * */   
public class ThreadStopLock {  //打印当前线程  public static void printCurrentAliveThread(){  Map<Thread, StackTraceElement[]> maps = Thread.getAllStackTraces();  Set<Entry<Thread, StackTraceElement[]>> set = maps.entrySet();  Iterator<Entry<Thread,StackTraceElement[]>> iterator = set.iterator();  System.out.println("System Alive Thread List:");  System.out.println("-------------------------");  while(iterator.hasNext()){  System.out.println("AliveThread_Name:"+iterator.next().getKey().getName());  }  System.out.println("-------------------------");  }public static void main(String[] args){  try {  //定义线程  Thread t0 = new Thread() {  public void run() {  try { for(long i=0;i<1000*1000*10;i++){  System.out.println(i);  }  System.out.println("thread death");  }catch (Throwable ex) {  System.out.println("Caught in run: " + ex);  ex.printStackTrace();  }  }  };  //开启线程  t0.start();  //等待2s之后挂起线程t0  Thread.sleep(2*1000);  //挂起线程  t0.suspend();  //打印当前的所有线程  printCurrentAliveThread();  //等待2s之后恢复线程  Thread.sleep(2*1000);  //复活线程  t0.resume();  }catch (Throwable t) {  System.out.println("Caught in main: " + t);  t.printStackTrace();  }  }  
}  

代码很简单的,定义一个线程,在线程中进行打印,在主线程中的逻辑是,先开启线程t0进行打印数据,等待2s之后将挂起线程t0,然后打印一下当前的活跃线程,然后再等待2s之后再复活t0线程继续打印!

但是结果不尽人意呀,结果很是惊讶的!运行结果:


好吧,开始打印,打印到311800(当然这个不是一定的),就停止了,但是这一停止不是停2s呀,是一直停着,这不是明显的死锁吗?导致t0.suspend后面的代码都不执行了,这就郁闷了,这个是为什么呢?纠结了一下午,打断点的时候才知道为什么,断点停在方法printCurrentAliveThread中的System.out.println()这行代码上,那就可以断定了,发生死锁的原因可能就是System.out.println方法,查看源代码:

public void println(String x) {  synchronized (this) {  print(x);  newLine();  }  } 
这个是PrintStream对象中的println方法,是个同步锁的方法,这时候应该就明白了,那么这个锁是什么呢?没错,这个所就是PrintStream对象,因为在t0线程中也有System.out.println,当调用suspend()方法调用的时候,这个方法是不会释放锁的,当然这个锁是同一个的,为什么呢?看一下System类中的out变量定义:
public final static PrintStream out = null;  
是static类型的,所以他是类上面的锁,肯定是同一个锁了,所以发生了死锁,

这时候我们将printCurrentAliveThread方法注释之后,运行就没有任何问题了。


就写到这里吧,好累,后面还有哦,继续关注吧!

原文地址:http://blog.csdn.net/jiangwei0910410003/article/details/19910517

这篇关于Java中的线程Thread方法之---suspend()和resume()的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048628

相关文章

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick