线程安全 - 在方法局部块内声明一个新线程

时间:2013-05-14 12:55:25

标签: java concurrency thread-safety

我很好奇以下代码是否是线程安全的:

public static void methodA () {
    // given that mutableObject is not thread-safe (no lock/synchronization used)
    MutableObject mo = new MutableObject();
    mo.setSomeValue(100);  // set an int value

    // the mutableList variable must be final in order to pass it to the thread block
    final List<mutableObject> mutableList = new ArrayList<mutableObject>();  
    mutableList.add(mo);
    Thread t = new Thread() {
                      @Override 
                      public void run() {
                          for (mutableObject e : mutableList) {
                              e.printIntValue();  // print 100 or 0?
                          }
                      }
                }
    t.start();
}

所以,这是问题所在。 即使没有使用显式同步/锁定,我也不确定新线程是否可以从“mutableList”引用中看到所有可访问的内容*。 (可见性问题)换句话说,新线程是打印0还是100?如果它没有看到主线程设置的值100,它将打印0,因为0是int数据类型的默认原始值。

即。 “内容可达”是指:

  1. MutableObject
  2. 持有的int值100
  3. 对ArrayList
  4. 持有的MutableObject的引用

    感谢您的回答。

2 个答案:

答案 0 :(得分:2)

此代码是线程安全的,因为没有任何其他线程可以访问相同的对象,因为它们在methodA()内和{的方法run()中可用线。两者都不会更改数据。

当至少2个线程运行相同的数据时,会出现线程安全问题。这不是你的情况。

如何使代码线程不安全? 有几种方法。

  1. 在致电mo.setSomeValue(100);后添加行t.start()。这意味着在启动线程后,有两个线程(您的主线程和另一个线程)操作同一个对象mo。但这不会导致例外。

  2. 添加行mutableList.remove(0)。如果您的线程足够快地启动并且在主线程到达之前设法进入循环以移除指令,则此可能导致ConcurrentModificationException

答案 1 :(得分:0)

这里没有线程安全的问题。 对象momutableList都在函数调用中定义和实例化。每次调用该函数时,都会创建2个新对象(上面)。没有任何线程不安全的值。