基本的に、このコードは http 要求を実行し、http 要求がタイムアウトした場合は、wifi 接続をリセットします (時々それを行う必要があります。それはまさにその通りです。「wifi をリセットする」の代わりに、Android 以外に関連するものにすることもできます。繋がり")。
次の特殊なケースを考慮する必要があります。
- 1 つ以上のスレッドが現在 http 要求を実行している場合、別のスレッドが Wi-Fi 接続をまだリセットできないようにする
- 1 つのスレッドが既に wifi 接続をリセットしており、別のスレッドが wifi 接続をリセットしようとしている場合は、後者のスレッドに直接送信して、代わりに http 要求を再試行します (前のスレッドが wifi のリセットを終了したとき)。
- Wi-Fi 接続が現在リセットされているときに http 要求を実行しない
- => 一度に 1 つのスレッドのみが wifi 接続を修正できますが、複数のスレッドが同時に http 要求を開始できます
それは私に頭痛を与えています。
これまでの私のコードは次のとおりです。何を改善できますか?
static int requestsActive = 0;
protected int requestTry = 0;
static final int maxTrys = 2;
static final ReentrantLock wifiLock = new ReentrantLock();
public void evaluate() throws Exception {
try {
requestTry++;
while (wifiLock.isLocked()) // no not start new http request while wifi is being fixed
Thread.sleep(400);
requestsActive++; //increment so that another thread that wants to fix wifi knows it has to wait
response = httpClient.execute(requestBase);
requestsActive--; // when == 0 wifi can be fixed if it needs to
} catch (ConnectTimeoutException e) {
requestsActive--; //same as above (for exception case)
if (requestTry == maxTrys)
throw new ConnectTimeoutException("maxTrys reached");
if (!wifiLock.tryLock()) //another thread is currently fixing wifi, no need to do it myself
evaluate(); // ...so start a new http request
while (requestsActive > 0) // wait until no more threads are in the http request section above
Thread.sleep(400);
WifiManager wifiMan = (WifiManager) App.getContext().getSystemService(Context.WIFI_SERVICE);
resetWifi(wifiMan); //reset android wifi, nothing special
wifiLock.unlock();
evaluate();
}