我不是CS大师也不是Java专家,所以如果以下问题的答案显而易见,请原谅我:
我已经构建了一个类来处理向HTTP服务器发送查询,获取响应并将响应返回给调用者。
我的问题是这个;如果我调用该函数一次,并且响应需要很长时间,并且在延迟期间,我再次调用它,延迟的第一次调用是否会干扰第二次调用的执行?
受欢迎的需求......这里有一些源代码:
package com.cambrothers.wms.module;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
public class ServerComm {
public HashMap<String, String> sendData(String endpoint, String requestParameters){
HashMap<String, String> response_data = new HashMap<String, String>();
System.out.println("GetRequest");
if (endpoint.startsWith("http://"))
{
// Send a GET request to the servlet
try
{
// Send data
String urlStr = endpoint;
if (requestParameters != null && requestParameters.length () > 0)
{
urlStr += "?" + requestParameters;
}
URL url = new URL(urlStr);
URLConnection conn = url.openConnection ();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null)
{
sb.append(line);
}
rd.close();
String result = sb.toString();
String[] values = result.split("&");
String[] kp = null;
for(int i =0; i < values.length ; i++){
kp = values[i].split("=");
response_data.put(kp[0], kp[1]);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
return response_data;
}
}
小心
答案 0 :(得分:2)
您所描述的复杂程度超过了典型的初级到中级程序员在大学课程之外的表现,这很好。但是让我们看一下你的问题所暗示的内容。
你说“我把这个功能称为一次,而且响应需要很长时间。”因此,我认为可以安全地假设您使用的同步请求函数在响应从服务器返回之前不会返回。
然后你说“在延迟期间,我再次打电话给你。”这意味着您正在使用threading,这是我在this SO answer中的高级详细信息中描述的概念。如果您不熟悉,请立即停止,阅读线程并真正理解它们,然后再尝试编写您的问题所描述的代码。熟悉吗?继续阅读。
现在问你的实际问题。
延迟的第一次通话是否会干扰第二次通话的执行?
不,不会有干扰from the kernel and JVM's point of view,因为单独的线程会单独执行。但是,从实际角度来看,是否存在干扰完全取决于您的代码。 Thread safety是一个很大的主题,无法在单个StackOverflow答案中解释,但它是关键所在。不过,我可以给出一些指示。请记住,这些指针指的是执行HTTP提取的函数。
如果您的HTTP提取功能是reentrant,则它自动是线程安全的。要重入,该函数不得引用任何可能被改变的静态或全局数据,并且不得调用任何不可重入的代码。您的函数很可能不引用静态数据,但您使用的HTTP库不可重入,因此您的HTTP提取功能也不可重入。
如果您的HTTP提取功能和/或其调用者使用正确的锁定(获得正确的锁定通常是一个非常困难的问题,大学课程可能会花两周的时间讲授锁定,避免死锁等) ,整个过程是线程安全的。我知道“正确锁定”被定义为“使进程线程安全的锁定”,因此这不是非常有用,但更有用的规则是锁定任何critical section。如果两个线程可能访问(并且一个或两个可能会改变)共享资源,那么您需要锁定对该共享资源的访问。请注意,您不仅需要锁定对资源的写访问权限,还需要锁定读访问权限。
如果您使用更多奇特的构造,如无锁数据结构,并且您显示正确性,那么您的程序是正确的。但是,这些更难做到。
请注意,如果所有程序数据和资源都是不可变的,则默认情况下所有函数都是可重入的,这意味着您的程序自动是线程安全的。在实践中,所有数据和资源完全不可变的程序有一点不尽如人意,但是如果你将可变性限制在程序的一个小区域并证明该区域的线程安全性,那么整个程序仍然是线程安全的。
答案 1 :(得分:0)
是和否但是我看到这是标记的Java,假设您正在调用HTTP Servlet?
应用程序服务器将生成/获取池化线程来为每个单独的调用/请求提供服务。
您的其他用户特定实施(例如修改/访问静态对象)将决定您的新通话是否会影响之前的通话。
答案 2 :(得分:0)
will the delayed first call interfere with the execution of the second call?
这完全取决于您的函数和服务器代码(HTTP服务器)的实现。没有更多信息,就无法回答这个问题。