Java 中的 Thread.stop 和它的朋友安全吗?

2024-06-24

The stop(), suspend(), and resume() in java.lang.Thread已被弃用,因为它们是unsafe http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html。 Oracle 建议的解决方法是使用Thread.interrupt(),但这种方法并不适用于所有情况。例如,如果您调用的库方法没有显式或隐式检查interruptedflag,您别无选择,只能等待通话结束。

所以,我想知道是否可以描述(可证明)安全调用的情况stop()在一个线程上。例如,是否安全stop()一个除了调用什么都不做的线程find(...) or match(...) on a java.util.regex.Matcher?

(如果有任何 Oracle 工程师正在阅读本文……我们将不胜感激。)

EDIT:答案只是重申了你不应该打电话的咒语stop()因为它已被弃用,不安全,无论什么没有抓住重点这个问题。我知道在大多数情况下它确实不安全,如果有可行的替代方案,您应该始终使用它。

这个问题是关于安全的子集情况。具体来说,what是那个子集吗?


这是我尝试回答我自己的问题。

我认为以下条件应该足以使单个线程安全停止Thread.stop():

  1. 线程执行不得创建或改变线程停止时其他线程可能可见的任何状态(即 Java 对象、类变量、外部资源)。
  2. 线程执行时不得使用notify正常执行期间的任何其他线程。
  3. 线程一定不能start or join其他线程,或与然后使用交互stop, suspend or resume.

(期限线程执行上面涵盖了所有应用程序级代码和线程执行的所有库代码。)

第一个条件意味着停止的线程不会使任何外部数据结构或资源处于不一致状态。这包括它可能在互斥体中访问(读取)的数据结构。第二个条件意味着可停止线程不能让其他线程处于等待状态。但它也禁止使用除简单对象互斥之外的任何同步机制。

可停止线程必须有一种方法将每个计算的结果传递给控制线程。这些结果是由可停止线程创建/改变的,因此我们只需确保它们在线程停止后不可见。例如,结果可以分配给 Thread 对象的私有成员,并使用线程自动表示其“完成”的标志进行“保护”。

EDIT: 这些条件非常严格。例如,为了安全停止“正则表达式求值器”线程,如果我们必须保证正则表达式引擎不会改变任何外部可见状态。问题是它可能会这样做,具体取决于您如何实现线程!

  1. The Pattern.compile(...)方法可能会更新已编译的静态缓存 模式,如果他们这样做,他们会(应该)使用互斥体来完成它。 (实际上,OpenJDK 6.0 版本不缓存模式,但 Sun 可能会改变这一点。)
  2. 如果您尝试通过在控制线程中编译正则表达式并提供预实例化来避免 1)Matcher,然后是正则表达式线程does改变外部可见状态。

在第一种情况下,我们可能会遇到麻烦。例如,假设使用 HashMap 来实现缓存,并且在重组 HashMap 时线程被中断。

在第二种情况下,我们就可以了provided认为Matcher尚未传递给其他线程,并且provided控制器线程没有尝试使用Matcher停止正则表达式匹配器线程后。

那么这会给我们带来什么影响呢?

好吧,我想我已经确定了线程理论上可以安全停止的条件。我还认为理论上可以静态分析线程的代码(及其调用的方法)以查看这些条件是否始终成立。但是,我不确定这是否真的实用。

这有道理吗?我错过了什么吗?

EDIT 2

当您考虑到我们可能试图杀死的代码可能不受信任时,事情会变得更加棘手:

  1. 我们不能依赖“承诺”;例如对不受信任的代码进行注释,表明它是可杀死的或不可杀死的。

  2. 实际上,我们需要能够根据已确定的标准,阻止不受信任的代码执行使其无法被杀死的操作。

我怀疑这需要修改 JVM 行为(例如,实现允许锁定或修改线程的运行时限制),或者隔离 JSR 的完整实现。这超出了我认为的“公平游戏”的范围。

因此,让我们暂时排除不受信任的代码情况。或者至少,承认恶意代码可能会导致自身无法安全地被杀死,并将这个问题放在一边。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中的 Thread.stop 和它的朋友安全吗? 的相关文章

  • 为 HTTPS 连接设置 https.protocols 系统属性时出现问题

    我有一个 Java 实现 各种客户端应用程序使用它来连接到第三方系统 这些第三方系统支持 http https 上的不同协议 在这种情况下 所有客户端应用程序都托管在我的 Java 实现托管的同一服务器中 因此 在这种情况下 各种客户端应用
  • 扩展 CrudRepository (Spring) 时是否需要 @Repository 注解?

    public interface CarRepository extends CrudRepository
  • 从 ArrayList Java 中的 HashMap 键中检索所有值

    美好的一天 这让我现在有点困惑 大脑冻结 并且似乎遗漏了一些东西 有一个 ArrayList 我用 HashMap 填充它 现在我放入 HashMap 和 arraylist Map put DATE value1 Map put VALU
  • RSA Java 加密和 Node.js 解密不起作用

    我有一个系统 需要在 javascript 中生成 RSA 密钥对 然后将公钥存储在服务器端的数据库中 作为字符串 然后 Java 中的服务器端将使用存储的公钥对字符串进行加密密钥并将其发送到客户端 客户端将使用私钥解密该字符串 我在客户端
  • 从 java 代码运行 Python 脚本

    这是我第一次在java中尝试python 我正在尝试从我的代码执行 python 脚本 如下所示 Process process Runtime getRuntime exec python C Users username Desktop
  • 为什么这个 Java 静态字段为空?

    public class StaticTest private static String a private static String b this is a public static void main String args a
  • 单击按钮时更改照片

    import javax swing Icon import javax swing ImageIcon public class Stage1 extends javax swing JFrame int score 0 int iter
  • Linux 上的 JavaFX

    Linux x86 和 x64 上的 JavaFX 情况如何 JavaFX 应用程序可以在 Linux 操作系统上顺利执行吗 我发现了 2011 年和 2012 年的一些问题 当时应用程序不稳定 目前发布的 JFX 版本是 2 2 4 在
  • Spring Data JPA 规范继承

    我有三个实体 如下所示 Entity Inheritance strategy InheritanceType JOINED DiscriminatorColumn name type public abstract class Emplo
  • 使用 Hashmap 理解两个或多个键

    我的哈希图有问题 在我的哈希映射方法中 我希望有两个或多个关键字作为键 而不是只有一个 例如 我希望用户输入一些包含两个或多个关键字的句子 假设 教授姓名 是关键字 例如 String temp3 instructor teacher me
  • StringBuilder - 重置或创建新的

    我有一个条件 StringBuilder 不断存储与大型平面文件 数百 MB 中的模式匹配的行 但是 在达到条件后 我将 StringBuilder 变量的内容写入文本文件 现在我想知道是否应该通过重置对象来使用相同的变量 gt strin
  • Java XPath API - 获取表示子树的字符串

    我的问题不是关于 xpath 语法 而是与 xpath 周围的 java API 有关 考虑以下 xml
  • 控制台中的 Java msg - 两个方法具有相同的方法签名但不提供可分配的类?

    在迁移到 java 1 8 时 我升级了项目中的许多依赖项 它是基于spring 4 3的应用程序 有很多外部依赖 例如 JMS HTTP客户端 FTP XML等 当应用程序启动时 我现在在控制台中收到以下消息 两个方法具有相同的方法签名但
  • 方法中缺少 return 语句错误

    我正在尝试编写一个返回计算机 MAC 地址字符串的静态方法 该函数本身可以在此处找到 http www mkyong com java how to get mac address in java http www mkyong com j
  • 在 libgdx 中截取屏幕截图

    我有一个应用程序 我想在其中截取游戏屏幕的屏幕截图并将其保存为图像并上传到 Facebook 我正在使用 Libgdx 我的重点是 android 谁能帮助我如何以编程方式截取游戏屏幕并将其另存为图像 现在相当容易 Libgdx提供了一个例
  • SwingWorker 和 Executor 的区别

    我正在使用 SwingWorker 在我正在制作的应用程序上执行一些重负载任务 虽然今天我遇到了 Executor 类和这个例子 Executors newCachedThreadPool execute new Runnable publ
  • JdbcTemplate queryForInt/Long 在 Spring 3.2.2 中已弃用。应该用什么来代替呢?

    JdbcTemplate 中的 queryforInt queryforLong 方法在 Spring 3 2 中已弃用 我无法找出为什么或什么被认为是使用这些方法替换现有代码的最佳实践 典型方法 int rowCount jscoreJd
  • 从java类文件获取apache webcontents文件夹的绝对路径[重复]

    这个问题在这里已经有答案了 需要在动态 Web 应用程序内获取 java 类文件中的绝对路径 实际上我需要获取 apache webapps 文件夹的路径 部署 webapps 的位置 e g apache root webapps my
  • 从不同的线程访问对象

    我有一个服务器类 它基本上等待来自客户端的连接 在该类中 我创建了一个 NetworkStream 对象 以便能够从客户端接收字节 由于 NetworkStream Read 方法不是异步的 这意味着它将等到从客户端读取字节才能继续执行类似
  • java中的“main”可以返回字符串吗?

    java中的public static void main String args 是否有可能返回String代替void 如果是 怎么办 public static String main String args 代替 public st

随机推荐