Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.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_Variables_Static - Fatal编程技术网

静态变量、线程和Java构造函数

静态变量、线程和Java构造函数,java,multithreading,variables,static,Java,Multithreading,Variables,Static,我从一本公认的样本书中看到了这一点,所以很难提出问题,然后我就不明白了 一个名为DataflightsService的类包含一个名为FlightFileAccess的私有静态变量,每当我们在构造函数中创建DataflightsService的新对象作为FlightFileAccess的初始化时,该变量都会被实例化 即 对我来说,这意味着每次创建dataflightssservice的实例时,构造函数中的静态变量FlightFileAccess 在原始的FlightFileAccess类中:我们

我从一本公认的样本书中看到了这一点,所以很难提出问题,然后我就不明白了

一个名为DataflightsService的类包含一个名为FlightFileAccess的私有静态变量,每当我们在构造函数中创建DataflightsService的新对象作为FlightFileAccess的初始化时,该变量都会被实例化


对我来说,这意味着每次创建
dataflightssservice
的实例时,构造函数中的静态变量
FlightFileAccess

在原始的
FlightFileAccess
类中:我们有一个remove方法来同步
RandomAccessFile

因此,因为我们使用了不同的
FlightFileAccess
引用,所以我们也使用了不同的
RandomAccessFile
引用

这意味着将
FlightFileAccess
作为静态服务在这里并不用于
RandomAccessFile
上的
同步,因为它每次都是新的,所以每个
DataflightsService
实例将在随机访问文件上执行它们的操作,而忽略同步。 与在静态启动器中实例化
FlightFileAccess
相反。我说得对吗


我希望能提供尽可能多的解释,以提供最好的方式,尽可能多地实例化
DataflightsService
(假设每个客户端都有自己的
DataflightsService
)在这之后,您可以同步一个文件以进行删除,例如,这样就不会出现多个客户端访问该文件的混乱情况。很抱歉,我需要为每个客户端包含一个
DataflightsService
,因为没有Cookie。

您的示例将无法编译,因为构造函数的名称与类不匹配。但是,如果您想命名构造函数
public DataflightsService()
,那么问题的一部分在于每次创建新对象时都会覆盖静态变量

听起来您希望这个静态变量只初始化一次。通常,您只需使用
private static final FlightFileAccess fileAccess=new FlightFileAccess()直接分配变量
或者,如果您想添加更多的逻辑,就像您有一个构造函数一样,您可以使用静态初始值设定项块,如下所示:

public class Dataflights {

    private static final FlightFileAccess fileAccess;

    static {
      // Static initializer block gets run once when the class is first referenced.
      // Not usually used unless you want to add more logic besides just initializing variables.
      fileAccess = new FlightFileAccess();
    }

    private final String path;
    public final int id;

    public Dataflights(String path) {
      this.path = path;
      this.id = fileAccess.generateId();
    }

  static class FlightFileAccess {

    private volatile int nextId = 0;
    synchronized public int generateId() {
      return nextId++;
    }
  }

  public static void main(String[] args) {
    Dataflights d = new Dataflights("my/path");
    System.out.println("Id is: " + d.id);
  }
}
有许多方法可以处理争用。如果您不熟悉Java并发性,我建议您这样做


您在FlightFileAccess类中所处的轨道是正确的。我看不到详细信息,但您可能还希望在
remove()
方法的签名中使用
synchronized
关键字来首先保护整个函数。然后,一旦你有了工作,就可以使用目标更明确的
同步{…}
块来减少单线程的代码量。

请编辑你的问题,将代码格式化为代码,并将其缩进。仅仅因为你在书中找到建议,这不会自动成为好的建议。构造函数是否无条件地分配静态字段?这听起来像是非常糟糕的设计。谢谢eric,这是一个错误,所以我修正了它,是的,基本上我想知道我的想法是否正确,因为我们需要使用同一个对象在线程上应用同步,在我提供的示例中,它在构造函数中实例化了静态对象,所以我觉得它是错误的,我认为在构造函数之前实例化要好得多。也感谢这本书的推荐,我已经听过很多次了,所以是的,我必须开始阅读它来理解所有的多重可能性,这不是一个静态构造函数。它是一个实例初始化程序块。它将有与构造函数相同的问题。顺便说一句,这将不会编译,因为该字段是最终字段。如果您的意思是静态初始值设定项块,那么语法是
static{…}
。但这是不必要的。您可以直接初始化静态变量,作为其声明的一部分。
Class FlightFileAccess{
    private RandomAccessFile database = null;
    private boolean remove(String code){
        // Other code goes here and there

        synchronized (database) {
             //Perform deletion code
        }
    }
public class Dataflights {

    private static final FlightFileAccess fileAccess;

    static {
      // Static initializer block gets run once when the class is first referenced.
      // Not usually used unless you want to add more logic besides just initializing variables.
      fileAccess = new FlightFileAccess();
    }

    private final String path;
    public final int id;

    public Dataflights(String path) {
      this.path = path;
      this.id = fileAccess.generateId();
    }

  static class FlightFileAccess {

    private volatile int nextId = 0;
    synchronized public int generateId() {
      return nextId++;
    }
  }

  public static void main(String[] args) {
    Dataflights d = new Dataflights("my/path");
    System.out.println("Id is: " + d.id);
  }
}