1

まず、やる気を起こさせる例を次に示します。

public class Algorithm
{
    public static void compute(Data data)
    {
        List<Task> tasks = new LinkedList<Task>();
        Client client = new Client();
        int totalTasks = 10;

        for(int i = 0; i < totalTasks; i++)
            tasks.add(new Task(data));

         client.submit(tasks);
    }
}

// AbstractTask implements Serializable
public class Task extends AbstractTask
{
    private final Data data;

    public Task(Data data)
    {
        this.data = data;
    }

    public void run()
    {
        // Do some stuff with the data.
    }
}

ですから、私はいくつかの並列プログラミングを行っており、多数のタスクを作成するメソッドを持っています。タスクは操作対象のデータを共有しますが、各タスクにデータへの参照を与えるのに問題があります。問題は、タスクがシリアル化されると、タスクごとにデータのコピーが作成されることです。さて、このタスククラスでは、データを静的に参照して1回だけ保存することができますが、これを行うことは、タスククラスのコンテキストではあまり意味がありません。私の考えは、オブジェクトを静的なものとして別の外部クラスに格納し、タスクにクラスからオブジェクトを要求させることです。これは、タスクが送信される前に実行できます。おそらく、上記の例の計算メソッドで実行できます。これは適切だと思いますか?誰かが提案されたアイデアに関する代替の解決策やヒントを提供できますか?ありがとう!

4

5 に答える 5

1

現在のこのシリアル化の状況について詳しく説明していただけますか?sはどのようにTask結果を報告し、それはどこに行きますか?彼らは結果を変更しDataますか?それらはいくつかの出力を生成しますか?すべてのタスクがすべてにアクセスする必要がありますDataか?のいずれかが同じTaskに書き込まれていObjectOutputStreamますか?

要約すると、私は2つのクラスのソリューションを見ることができると思います。

  1. Taskすべてのがすべてにアクセスする必要がない場合は、必要なデータのみDataをそれぞれに提供しようとしTaskます。
  2. それらがすべてそれを必要とする場合、それ自体をTask含むのではなくData、データを取得するために使用できるある種のIDを含むようにします。全体的な状況をよりよく理解することなしに、実行できるData各場所に転送されたコピーを1つだけ取得し、それにアクセスできるようにする方法はわかりません。ただし、個別に管理することをお勧めします。TaskTaskData
于 2009-07-03T09:29:08.557 に答える
0

静的にする代わりにシングルトンを作成することを検討しましたか?

于 2009-06-30T15:42:29.503 に答える
0

私の考えは、オブジェクトを静的として別の外部クラスに保存し、タスクにクラスからオブジェクトを要求させることです。

この考えは忘れてください。タスクがシリアル化され、ネットワーク経由で送信される場合、そのオブジェクトは送信されません。静的データは、JVM 間で共有されることはありません (共有できません)。

基本的に、タスクが個別にシリアル化されている場合、データを共有する唯一の方法は、データを個別に送信するか、1 つのタスクでのみ送信して、受信側のマシンで他のタスクに取得させることです。これは、データ セットを持つ 1 つのタスクと他のクエリがクエリを実行する静的フィールドを介して発生する可能性がありますが、もちろん、その 1 つのタスクを最初に実行する必要があります。また、同期の問題が発生する可能性があります。

しかし実際には、タスクが自己完結型であると想定するある種の処理キューを使用しているように思えます。それらにデータを共有させようとすることは、その概念に反することになります。とにかくあなたのデータはどれくらいの大きさですか?データを共有することは本当に絶対に必要ですか?

于 2009-07-03T09:43:50.220 に答える
0

編集:質問された内容について誤解しているため、以下の回答は実際には関係ありません。質問の作成者からの詳細を保留して、ここに残します。


これがまさにtransientキーワードが発明された理由です。

インスタンス フィールドがオブジェクトの既定のシリアル化された形式の一部ではないことを宣言します。オブジェクトがシリアル化されると、その非一時的なインスタンス フィールドの値のみが既定のシリアル表現に含まれます。オブジェクトが逆シリアル化されると、一時フィールドはデフォルト値にのみ初期化されます。

public class Task extends AbstractTask {
    private final transient Data data;

    public Task(Data data) {
        this.data = data;
    }

    public void run() {
        // Do some stuff with the data.
    }
}
于 2009-06-30T15:19:43.183 に答える
0

質問を完全に理解しているかどうかはわかりませんが、Task は後で実行するために実際にシリアル化されているように思えます。

この場合、重要な問題は、すべてのTaskオブジェクトが同じ に書き込まれるかどうかObjectOutputStreamです。その場合、Dataは最初に検出されたときにのみシリアル化されます。後の「コピー」は、ストリームから同じオブジェクト ハンドルを参照するだけです。

おそらく、これを利用してデータへの静的参照を回避できます (オブジェクト指向設計で多くの問題を引き起こす可能性があります)。

于 2009-06-30T15:21:24.243 に答える