3

私は CS の第一人者でも Java の専門家でもないので、次の質問に対する答えが明らかである場合はご容赦ください。

HTTP サーバーへのクエリの送信、応答の取得、および呼び出し元への応答を処理するクラスを作成しました。

私の質問はこれです。その関数を 1 回呼び出して、応答に時間がかかり、遅延中にもう一度呼び出した場合、遅延した最初の呼び出しが 2 番目の呼び出しの実行に干渉しますか?

一般的な要求により...ここにいくつかのソースコードがあります:

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

あなたが説明している複雑さのレベルは、大学のコースの外で一般的な初級から中級レベルのプログラマーが受ける以上のものです。これは良いことです。しかし、あなたの質問が何を意味するのか見てみましょう。

「その関数を一度呼び出すと、応答に時間がかかる」とおっしゃっています。したがって、サーバーから応答が返されるまで返されない同期要求関数を使用していると想定しても安全だと思います。

それからあなたは「遅れている間に、私はそれを再び呼ぶ」と言います。これは、スレッドを使用していることを意味します。これは、このSO回答で高レベルの詳細を説明する概念です。慣れていない場合は、今すぐ停止し、スレッドを読んで、スレッドを本当に理解してから、質問で説明されているコードを記述してください。見慣れた?読み続けます。

さて、あなたの実際の質問に移りましょう。

遅延した最初の呼び出しは、2番目の呼び出しの実行に干渉しますか?

いいえ、別々のスレッドが別々に実行されるため、カーネルとJVMの観点からの干渉はありません。ただし、実際的な観点から、干渉があるかどうかはコードに完全に依存します。 スレッドセーフは大きなトピックであり、StackOverflowの単一の回答では説明できませんが、ここで重要です。しかし、私はいくつかの指針を与えることができます。これらのポインタは、HTTPフェッチを実行する関数を参照していることに注意してください。

  1. HTTPフェッチ関数が再入可能である場合、それは自動的にスレッドセーフです。再入可能であるためには、関数は、変更される可能性のある静的データまたはグローバルデータを参照してはならず、非再入可能コードを呼び出してはなりません。関数が静的データを参照していない可能性は十分にありますが、使用しているHTTPライブラリは再入可能ではないため、HTTPフェッチ関数も再入可能ではありません。

  2. HTTPフェッチ関数やその呼び出し元が適切なロックを使用している場合(ロックを正しく取得することは通常、非常に難しい問題であり、大学のコースでは、ロックやデッドロックの回避などについて2週間分の講義が行われる可能性があります)、プロセス全体はスレッドセーフです。 。「適切なロック」は「プロセスをスレッドセーフにするロック」として定義されていることを知っているので、これはそれほど役に立ちませんが、より有用なルールはクリティカルセクションをロックすることです。2つのスレッドが共有リソースにアクセスする可能性がある場合(および一方または両方が変更する可能性がある場合)、その共有リソースへのアクセスをロックする必要があります。リソースへの書き込みアクセスだけでなく、読み取りアクセスもロックする必要があることに注意してください。

  3. ロックフリーデータ構造のようなよりエキゾチックな構造を使用し、正確さを示す場合、プログラムは正しいです。ただし、これらを正しく理解するのはさらに困難です。

すべてのプログラムデータとリソースが不変である場合、すべての関数はデフォルトで再入可能であることに注意してください。つまり、プログラムは自動的にスレッドセーフになります。実際には、すべてのデータとリソースが完全に不変であるプログラムは、少し望まれることはありませんが、プログラムの小さな領域に可変性を制限し、その領域のスレッドセーフを証明した場合でも、プログラム全体はスレッドセーフです。

于 2012-05-30T03:45:19.087 に答える
0

はい、いいえ。しかし、これは Java とタグ付けされているようですが、HTTP サーブレットを呼び出していると仮定しますか?

アプリケーションサーバーは、プールされたスレッドを生成/取得して、個々の呼び出し/要求にサービスを提供します。

ユーザー固有の実装の残りの部分 (静的オブジェクトの変更/アクセスなど) は、新しい呼び出しが以前の呼び出しに影響を与えるかどうかを決定します。

于 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 に答える