1

インスタンスを分類するためのリクエストを取得するマルチスレッド Java アプリケーションを実行しています。多くのスレッドを同時に実行できるようにするために、私のアプリケーションはスレッド間でClassifierオブジェクトとオブジェクトを共有しますInstances。Instances オブジェクトには属性の関連データのみが含まれ、関連付けられたインスタンスはありません。

アプリケーションが分類リクエストをInstance受け取ると、リクエストの属性データを使用してオブジェクトを作成し、事前に生成さInstancesれたオブジェクトを を使用してデータセットとして設定します。次にInstance.setDataset()例を示します。

myNewInstance.setDataset(sharedInstances);

次にmyNewInstance、共有に送信されClassifierます。

ほとんどの場合、うまくいくようです。ただし、2 つの同時要求が発生すると、 から例外がスローされることがありClassifier.distributionForInstance()ます。残念ながら、エラー メッセージは明確ではありませんが、これらは 2 つの異なる例外です。

Caused by: java.lang.RuntimeException: Queue is empty
at weka.core.Queue.pop(Queue.java:194)
at weka.filters.Filter.output(Filter.java:563)
at weka.filters.unsupervised.attribute.PrincipalComponents.convertInstance(PrincipalComponents.java:626)
at weka.filters.unsupervised.attribute.PrincipalComponents.input(PrincipalComponents.java:812)
at weka.classifiers.meta.RotationForest.convertInstance(RotationForest.java:1114)
at weka.classifiers.meta.RotationForest.distributionForInstance(RotationForest.java:1147)

Caused by: java.lang.NullPointerException
at weka.filters.unsupervised.attribute.Standardize.convertInstance(Standardize.java:238)
at weka.filters.unsupervised.attribute.Standardize.input(Standardize.java:142)
at weka.filters.unsupervised.attribute.PrincipalComponents.convertInstance(PrincipalComponents.java:635)
at weka.filters.unsupervised.attribute.PrincipalComponents.input(PrincipalComponents.java:812)
at weka.classifiers.meta.RotationForest.convertInstance(RotationForest.java:1114)
at weka.classifiers.meta.RotationForest.distributionForInstance(RotationForest.java:1147)

ご覧のとおり、最新の場合、空のメッセージ文字列が表示されます。

私の理解では、オブジェクトを不変にすることはできず、同時実行性を最大限に活用するために、この部分をクリティカルセクションにラップしたくありません。コンストラクターを使用して、分類要求ごとに異なる「インスタンス」オブジェクトを作成しようとしましたが、Instances(Instances dataset)異なる結果は得られませんでした。Classifierオブジェクトの構築に時間がかかりすぎて、高速に応答する必要があるため (最大で 10 ~ 20 ミリ秒)、別のものを使用することはできません。私の理解では、問題はそこに依存していません。

問題は、同じ Instances オブジェクトを使用することにあると思います。インスタンスのドキュメントに基づいて、コンストラクターは、別のオブジェクトを作成しても問題が解決されなかった理由を説明するヘッダー情報への参照のみをコピーします。すべての属性をリアルタイムで調べずに、以前のオブジェクトに基づいて完全に異なるインスタンス オブジェクトを作成するオプションはありますか?

その他のパフォーマンス指向のソリューションも高く評価されます。

ありがとう!

4

1 に答える 1

4

おそらく、この問題はすでに解決済みです。これは、同様の問題に直面している人のためのものです。マルチスレッド Java アプリケーションでインスタンスをテストしていたところ、同じ例外に直面しました。問題を分解するために、あなたのケースには2つの問題があります:

  • 1 つ目は、Instances各リクエストのデータを設定している同じオブジェクトを使用していることです。これにより、コードを壊すことはないかもしれませんが、間違った結果をもたらす可能性のある並行性の問題に遭遇する可能性が高くなります。異なるリクエストからのデータが混同される可能性があるためです。最善の策は、Instancesリクエストごとに新しいオブジェクトを作成することです。ただし、これは直面している例外を生成しているものではありません。2番目の問題です。
  • 2 番目の問題は、同じ を使用していることですClassifier。これが例外の原因です。私の場合、分類子を構築してからシリアライズし、ファイルに書き込みました。テスト セットを分類する必要がある場合は、各スレッドでオブジェクトをデシリアライズして、新しいインスタンスを作成していました。ただし、この問題を解決する適切な方法は、weka.classifiers.Classifier.makeCopy(model)静的メソッドを使用して要求ごとにコピーを作成することです。これは、内部的にシリアライゼーションを使用します。
于 2013-08-21T00:07:05.633 に答える