私は自分のサービスへのREST呼び出しによって新しいスレッドを作成するバックエンドサービスを構築しています。スレッドが5分かかると何も受け取らない場合、スレッドは別のREST呼び出しを待機します。 すべてのスレッドを追跡するために、現在実行中のすべてのスレッドを追跡するコレクションがあるため、ユーザーがアクションを受け入れたり却下したりするなど、REST呼び出しが最後に来ると、userIDを使用してそのスレッドを識別できます。そのスレッドが受け入れられた場合、そのスレッドが次のアクションを実行することができる場合は、そのスレッドをコレクションから削除します。私は同時実行性の問題を避けるためにこれをConcurrentMapを使って実装しました。ConcurrentMapにスレッドを格納するのは安全ですか?
これは私がスレッドで作業して初めてのので、発生する可能性のある問題を見落とさないようにしたいと考えています。私のコードを見て、私がそれをより良くすることができるか、または欠陥があるかどうかを教えてください。
public class UserAction extends Thread {
int userID;
boolean isAccepted = false;
boolean isDeclined = false;
long timeNow = System.currentTimeMillis();
long timeElapsed = timeNow + 50000;
public UserAction(int userID) {
this.userID = userID;
}
public void declineJob() {
this.isDeclined = true;
}
public void acceptJob() {
this.isAccepted = true;
}
public boolean waitForApproval(){
while (System.currentTimeMillis() < timeElapsed){
System.out.println("waiting for approval");
if (isAccepted) {
return true;
} else if (declined) {
return false;
}
}
return isAccepted;
}
@Override
public void run() {
if (!waitForApproval) {
// mustve timed out or user declined so remove from list and return thread immediately
tCollection.remove(userID);
// end the thread here
return;
}
// mustve been accepted so continue working
}
}
public class Controller {
public static ConcurrentHashMap<Integer, Thread> tCollection = new ConcurrentHashMap<>();
public static void main(String[] args) {
int barberID1 = 1;
int barberID2 = 2;
tCollection.put(barberID1, new UserAction(barberID1));
tCollection.put(barberID2, new UserAction(barberID2));
tCollection.get(barberID1).start();
tCollection.get(barberID2).start();
Thread.sleep(1000);
// simulate REST call accepting/declining job after 1 second. Usually this would be in a spring mvc RESTcontroller in a different class.
tCollection.get(barberID1).acceptJob();
tCollection.get(barberID2).declineJob();
}
}
'Thread'を拡張しないでください。代わりに 'Runnable'または' Callable'を実装してください。それらを実行するには 'ExecutorService'を使います。スレッドを使い始めたばかりの人にとっては、あなたはあまりにも賢いようにしようとしています。 'CompletableFuture'もここでは適しています。 – Kayaman
コードには何が起こったのですか?これはコンパイル可能ではありません。 「公的」は存在しない。あなたの入力アシスタントが自動修正を行っている携帯電話に入力しましたか? – Lothar
@Kayaman Yea私は自分自身のために物事をより複雑にしていることに同意します。私はExecutorServiceを使うことを考えていましたが、後でそのスレッドへの参照を得ることができるので、私は仕事を受け入れることができますか? – Claudiga