まず、(データを取得するとき、それらはすべて同じスタイルについて見えるが、異なるシステムライブラリ関数を呼び出す):
は、ここでの関数のいずれかのために私のコードです"何が起こるかについての貧弱な記述です。例外はありますか?正確にはどうなりますか?
次に、APIへのアクセスを同期する必要がありますか? Java APIが提供されている場合、このAPIがすでに同期されている可能性があり、セマフォーは不要です。
セマフォを取得した場合は、finallyブロックで解放する必要があります。これは、tryブロックの内部で起こるものは何でも、それがリリースされることを保証:
ticket.acquire();
try {
...
}
catch (...)
finally {
ticket.release();
}
第四:私はwhile(true)
ループのポイントを理解していません。ループするのは、InterruptedExceptionが存在するときだけです。 InterruptedExceptionは、ASAPの実行を停止すべきであることをスレッドに通知するために使用されます。したがって、あなたのメソッドはそれを飲み込む代わりにこの例外をスローする必要があります。
最後に、Java命名規則を学び、それらに固執する必要があります。メソッドは小文字で始まります。
public int readInt(int min, int max) throws QuantisException, InterruptedException {
ticket.acquire();
try {
return quantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
}
finally {
ticket.release();
}
}
一つだけのスレッドがネイティブライブラリ関数にアクセスできることを確認したい場合は、そのようなクラスを使用する:あなたは本当にここで私はメソッドを書き換えるだろうかこれで、アクセスを同期する必要が提供
:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class SingleThreadAccess {
public static final SingleThreadAccess INSTANCE = new SingleThreadAccess();
private ExecutorService executor;
// to be called by ServletContextListener.contextInitialized()
public void init() {
executor = Executors.newSingleThreadExecutor();
}
// to be called by ServletContextListener.contextDestroyed()
public void shutdown() {
executor.shutdown();
try {
executor.awaitTermination(2L,TimeUnit.SECONDS);
}
catch (InterruptedException e) {
}
executor.shutdownNow();
}
public int readInt(int min, int max) throws QuantisException, InterruptedException {
Callable<Integer> task = new Callable<Integer>() {
@Override
public Integer call() throws QuantisException {
return quantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
}
};
Future<Integer> future = executor.submit(task);
try {
future.get();
}
catch (ExecutionException e) {
unwrap(e);
}
}
private void unwrap(ExecutionException e) throws QuantisException {
Throwable t = e.getCause();
if (t instanceof QuantisException) {
throw (QuantisException) t;
}
throw new RuntimeException(e);
}
}
こんにちは、入力していただきありがとうございます。クラッシュを言うと、私はデバイスに要求する複数の接続があるとき、Tomcatサーバーがクラッシュし、ログ出力:
セマフォを実装すると、複数の接続送信でテストするまで実際にはうまく動作しますリクエストを本当に速く(リフレッシュする)ことができます。 ありがとう、私はあなたがちょうど言ったことをしようとします。 –ああ、ほとんど忘れていた:いいえ、APIはJava APIではありません。これは、Javaラッパーを持つCライブラリーです。私が見るものから、私はそれが同期しているとは思わない。また、私はまったくセマフォーを実装する前に、すぐにクラッシュします。もしリクエストを本当に速く3回だけリフレッシュすれば、例外はなく、エラーメッセージはJVMの外部からエラーが出ていると言いますが、Cライブラリから来ていると確信しています。現在のスレッドを使用します。 –
私はネイティブコードの専門家ではありませんが、たぶん1つのスレッドだけを呼び出すときでさえ、複数のスレッドでは全く使用できません。この場合、1つのスレッドをAPIの使用専用にする必要があります。それが事実なら(それは文書化されるべきです!)、あなたはやり方を知らないので、別の質問をしてください。そして、私は幸せになるでしょう。 –