Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果方法不使用对象';那么它是线程安全的吗?_Java_Multithreading_Thread Safety - Fatal编程技术网

Java 如果方法不使用对象';那么它是线程安全的吗?

Java 如果方法不使用对象';那么它是线程安全的吗?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,如果对象的公共方法仅使用传递的参数和局部变量,则 我们可以说它是线程安全的吗?所谓的线程安全确实是线程安全的,但前提是绝对没有副作用(即,通过改变参数传入的对象) 是的,它是线程安全的。它不能干扰其他方法的调用。(除非它还有其他严重的副作用。) 此方法的指令与任何其他方法的指令的任何交错都是可以的。如果未修改本地memeber变量,并且未更改传递参数的状态(即通过这些参数上的方法),则它是线程安全的 此外,如果传递的参数是对象,将其设为最终参数并不能保证线程安全 public class Foo

如果对象的公共方法仅使用传递的参数和局部变量,则


我们可以说它是线程安全的吗?

所谓的线程安全确实是线程安全的,但前提是绝对没有副作用(即,通过改变参数传入的对象)

是的,它是线程安全的。它不能干扰其他方法的调用。(除非它还有其他严重的副作用。)

此方法的指令与任何其他方法的指令的任何交错都是可以的。

如果未修改本地memeber变量,并且未更改传递参数的状态(即通过这些参数上的方法),则它是线程安全的

此外,如果传递的参数是对象,将其设为最终参数并不能保证线程安全

public class Foo{
    private int count = 1;
    public void incrementFoo(){
        count += 1;
    }
    public int getFoo(){
        return count;
    }
}


视情况而定。有一些方法很容易使它不线程安全

首先,如果传递到方法中的任何参数都不是线程安全的,并且您的方法在没有适当同步的情况下以多线程方式使用它,那么它就不是线程安全的。比如说,

// HashMap is not thread safe
public void foo(String key, HashMap<String,String> map) {
  String value = map.get(key);
  if (value == null) {
    map.put(key, "new value");
  }
}

如果有其他线程在此队列上等待并开始使用map对象,则map对象已转义,并且存在相同的线程安全问题。

所有参数都是不可变的吗?@DaDaDom它们没有标记为“final”,但在方法体中不会更改。你认为它们应该被标记为最终的吗?是的,如果没有副作用,并且该方法不使用静态局部变量,那么就没有理由要求不修改局部变量。现在当我想到它时,我可能误解了这个问题。我认为局部变量是调用方法的类的局部变量。可能的意思是-方法范围内的局部变量。在foo示例中,我将“multiplier”视为本地变量。通常,
multiplier
将被称为成员变量。局部变量仅在您提到的当前正在执行的方法的范围内。已修复该问题。对不起,我的无能。所有这些都可以被认为是“副作用”在上面的答案。以下是一些具体的例子。这是为了说明局部方法调用在线程安全方面更容易处理,但肯定不能免疫它。
// HashMap is not thread safe
public void foo(String key, HashMap<String,String> map) {
  String value = map.get(key);
  if (value == null) {
    map.put(key, "new value");
  }
}
public void foo() {
  Map map = ...; // create and populate the map
  ListenerQueue.getQueue().add(map); // there are listener threads waiting on this queue
  // do some other work
}