java - 为什么我要检查一个 Runnable,它的线程不为空​​?

标签 java runnable

我在我正在接管的项目中发现了这样的代码。我不确定 if 条件应该完成什么。如果 Runnable 正在运行,它会在检查 null 的线程中执行此操作。所以情况总是如此,对吗?

public class Outer 
{
    Thread m_thread = null;

    public Outer() 
    {
         Runnable runner = new Runnable()
         {
             public void run()
             {
                 if ( m_thread != null )
                     do_stuff();
             }
         };

         m_thread = new Thread(runner);
         m_thread.start();
    }
}

实际上还有另一种方法,将 m_thread 设置为 null,但由于可运行对象中没有循环,这有什么区别吗? do_stuff() 不访问 m_thread

最佳答案

由于 m_thread 未标记为 volatile 或由任何其他内存屏障操作保护,因此当 Runnable 运行时,它可能会观察到 m_threadnull。如果 do_stuff() 需要对 m_thread 的非空引用,则代码将失败。

检查Safe Publication and Safe Initialization in Java Shipilev 的文章了解 Java 中的安全发布习惯用法。简而言之:

There are a few trivial ways to achieve safe publication:

  • Exchange the reference through a properly locked field (JLS 17.4.5)
  • Use static initializer to do the initializing stores (JLS 12.4)
  • Exchange the reference via a volatile field (JLS 17.4.5), or as the consequence of this rule, via the AtomicX classes
  • Initialize the value into a final field (JLS 17.5).

关于java - 为什么我要检查一个 Runnable,它的线程不为空​​?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51206078/

相关文章:

java - Android : Maps not zooming in to my location, 沿 Y 坐标随机位置

java - Activity 结束后停止 Handler Runnable

java - ScheduledExecutorService 仅使用 switch 语句执行一次

java - 将 Eclipse 项目导出到 Runnable Jar 不起作用

java - 请求参数的存在应评估为真

java - Jax-rs apache-cxf :No resource methods have been found for resource class

java - 我的 CipherOutputStream 无声地失败

java - Android:不可转换的类型;无法将 android.preference.Preference 转换为 androidx.preference.SeekBarPreference

Java:守护进程:thread.join() 未完成,之前在一个线程中抛出异常

android - Android 中的 Async Task、Runnable 和 Handler 哪个更好