Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.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
在JavaWeb应用程序中使用静态方法和变量_Java_Web Applications_Autocomplete_Static - Fatal编程技术网

在JavaWeb应用程序中使用静态方法和变量

在JavaWeb应用程序中使用静态方法和变量,java,web-applications,autocomplete,static,Java,Web Applications,Autocomplete,Static,我在我的web应用程序的标题中有一个搜索框,并使用autocomplete帮助用户按作者姓名或书名查找书籍。在用户输入时,oninput()函数通过ajax调用servletFindBooksFindBooksservlet调用类SuggestionBook的静态方法SuggestionBook(),该方法返回与输入字符串匹配的书籍数组 FindBooks.java JSONArray books = SuggestionBook.suggest(inputString); out.prin

我在我的web应用程序的标题中有一个搜索框,并使用autocomplete帮助用户按作者姓名或书名查找书籍。在用户输入时,
oninput()
函数通过
ajax
调用servlet
FindBooks
FindBooks
servlet调用类
SuggestionBook
的静态方法
SuggestionBook()
,该方法返回与输入字符串匹配的书籍数组

FindBooks.java

 JSONArray books = SuggestionBook.suggest(inputString);
 out.print(books);
SuggestionBook.java

 private static boolean isTernaryEmpty = true;
 private static Ternary ternary;

 private static void fillTernary() {
  // fills ternary search tree with data.
  isTernaryEmpty = false;
 }

 public static JSONArray suggest(String searchString) {
  if(isTernaryEmpty) {
    fillTernary();
  }
  return ternary.find(searchString);
 } 

我在类
SuggestionBook.java
中使用了
static
方法,以避免为应用程序的每个会话加载数据。因此,它将只加载一次,然后可以由不同的会话共享。但是,由于静态方法只有一个副本,并且所有会话都使用相同的
static
方法来获取数据。他们是否必须等待其他会话使用该方法,或者所有会话都可以同时访问该方法?如果是,是否会影响应用程序的性能。如果否,JVM如何管理对单个副本的并发访问?最后,据我所知,只要class
SuggestionBook
没有被垃圾收集,数据就会留在内存中。将数据结构用作
类变量
而不是
实例变量
是否是正确的方法,因为它们会在更长时间内阻塞可用内存。

您可以将建议方法设为同步,并且它会工作。因为只有第一个调用将填充树中的数据,而后续调用只读取它

但是,如果同步suggest方法,则调用suggest的每个线程都将同步,这是不必要的,因为第一次调用已经填充了树

解决方案1)创建一个静态块并初始化其中的树。这样,一旦类被加载,树就会被初始化

解决方案2)使“FillTriangal”方法同步,并且仅当未初始化时才在方法内部初始化树,即if(isTernaryEmpty)。请注意,两种方法都需要if条件,以防止多个线程同时初始化

他们是否必须等待其他会话使用该方法,或者所有会话都可以同时访问该方法

不,他们不必等待,是的,他们可以同时访问

同时从多个会话访问同一对象可能是一个复杂的过程 问题,但不一定是。例如,如果执行两个会话 在不更改对象状态的情况下同时访问对象 好的如果它们确实改变了状态,并且状态转换涉及不稳定 中间状态可能会出现问题

如果两个线程同时运行同一个方法,那么它们的代码指针都指向该方法,并且在堆栈上都有自己的参数和局部变量副本。只有当堆栈上的对象指向堆上的相同对象时,它们才会相互干扰

如果是,是否会影响应用程序的性能。如果否,JVM如何管理对单个副本的并发访问

java中的内存分为两类:堆和堆栈。堆是所有对象所在的地方,堆栈是线程工作的地方。每个线程都有自己的堆栈,不能访问彼此的堆栈。每个线程还有一个指向代码的指针,该指针指向当前正在运行的代码位。当线程开始运行新方法时,它会将该方法中的参数和局部变量保存在自己的堆栈中。其中一些值可能是指向堆上对象的指针

最后,据我所知,只要类SuggestionBook没有被垃圾收集,数据就会留在内存中。使用数据结构作为类变量而不是实例变量是否是正确的方法,因为它们会在更长的时间内阻塞可用内存

因为您使用的是servlet,所以在webapp启动时,servlet的单个实例只创建一次,并在所有请求之间共享。无论是否是静态的,每个类/实例变量都将在所有请求/会话之间共享。 Servlet只有一个实例,实例变量的作用类似于静态变量。因此,它不要求人们通过将变量设置为静态而不是实例来了解单个实例(因为许多人不知道),而是消除了使用中的任何混乱。因此,变量的意图更清晰,不易被误解。因此,是的,从可用性来看,这不是一个坏方法。

请了解如果答案没有帮助,您可以发表评论,要求此人做出更多澄清。