3

我不是 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;
}
}

小心

4

3 回答 3

2

您所描述的复杂程度超过了典型的初学者到中级程序员在大学课程之外所承担的复杂程度,这很好。但是让我们看看你的问题意味着什么。

你说“我调用了那个函数一次,响应时间很长。” 所以我认为可以安全地假设您正在使用一个同步请求函数,该函数在响应从服务器返回之前不会返回。

然后你说“在延迟期间,我再次调用它”。这意味着您正在使用threading,这是我在此 SO answer中详细描述的概念。如果您不熟悉,请立即停止,阅读线程并真正理解它们,然后再尝试编写您的问题描述的代码。熟悉的?继续阅读。

现在到你的实际问题。

延迟的第一个呼叫会干扰第二个呼叫的执行吗?

不,从内核和 JVM 的角度来看不会有干扰,因为单独的线程是单独执行的。但是,从实际的角度来看,是否会有干扰完全取决于您的代码。 线程安全是一个很大的话题,无法在单个 StackOverflow 答案中解释,但它是这里的关键。不过,我可以给出一些指示。请记住,这些指针指的是执行 HTTP 获取的函数。

  1. 如果您的 HTTP 获取函数是可重入的,它会自动成为线程安全的。要可重入,该函数不得引用任何可能发生变异的静态或全局数据,并且不得调用任何不可重入代码。您的函数很可能没有引用静态数据,但您使用的 HTTP 库不是可重入的,因此您的 HTTP 获取函数也不是可重入的。

  2. 如果您的 HTTP 获取函数和/或其调用者使用正确的锁定(正确锁定通常是一个非常困难的问题,大学课程可能会花费两周的时间讲授锁定、避免死锁等),整个过程是线程安全的. 我知道“适当的锁定”被定义为“使进程线程安全的锁定”,所以这并不是很有帮助,但更有用的规则是锁定任何关键部分。如果两个线程可能访问(并且一个或两个线程可能会发生变异)共享资源,那么您需要锁定对该共享资源的访问。请注意,您不仅需要锁定对资源的写访问权限,还需要锁定读访问权限。

  3. 如果您使用更奇特的结构,例如无锁数据结构,并且您显示了正确性,那么您的程序就是正确的。不过,这些更难做到。

请注意,如果您的所有程序数据和资源都是不可变的,则默认情况下所有函数都是可重入的,这意味着您的程序自动是线程安全的。在实践中,所有数据和资源都完全不可变的程序有一些不足之处,但是如果您将可变性限制在程序的一个小区域并证明该区域的线程安全性,那么您的整个程序仍然是线程安全的。

于 2012-05-30T03:45:19.087 回答
0

是和否。但我看到这是标记为 Java,假设您正在调用 HTTP Servlet?

应用程序服务器将产生/获取一个池线程来服务每个单独的调用/请求。

您的用户特定实现的其余部分(例如修改/访问静态对象)将确定您的新调用是否影响您以前的调用。

于 2012-05-30T03:27:21.327 回答
0
will the delayed first call interfere with the execution of the second call?

这完全取决于您的函数和服务器代码(HTTP 服务器)的实现。没有更多信息是不可能回答这个问题的。

于 2012-05-30T03:27:22.963 回答