Java.lang.IllegalMonitorStateException при выполнении AsyncTask для нескольких раз

Я ссылаюсь на это решение для запуска AsyncTask в течение нескольких времен. Но я получаю следующую ошибку, когда вызываю tryAgain.signal();

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.webapi_testing, PID: 3951
java.lang.IllegalMonitorStateException 
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1917)
at com.medimanage.webapi_testing.AsyncHttpRequest_Recursive.runAgain(AsyncHttpRequest_Recursive.java:156)
at com.medimanage.webapi_testing.AsyncHttpRequest_Recursive.onProgressUpdate(AsyncHttpRequest_Recursive.java:145)
at com.medimanage.webapi_testing.AsyncHttpRequest_Recursive.onProgressUpdate(AsyncHttpRequest_Recursive.java:17)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:648)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5052)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)

следующий - мой класс asyncTask;

public class AsyncHttpRequest extends AsyncTask<Void, String, String> {

    private String UrlString = "";
    private boolean _showProgressDialog = false;
    private ProgressDialog Dialog;
    private Context mContext;
    private IHttpRequestCompletedListener listener;
    private boolean isActivity = true;
    private String _messageText = "Please wait..."; 
    private String type = "get";
    private HttpUtility utility;

    private final ReentrantLock lock = new ReentrantLock();
    private final Condition tryAgain = lock.newCondition();
    private volatile boolean finished = false;
    boolean lockAcquired = false;

    public AsyncHttpRequest(String urlString, Context context, IHttpRequestCompletedListener listener, boolean _showProgressDialog) {
        UrlString = urlString;
        this._showProgressDialog = _showProgressDialog;
        this.mContext = context;
        this.listener = listener;
        Dialog = new ProgressDialog(this.mContext);
        this.utility = new HttpUtility(this.UrlString, mContext, listener);
    }

    public void addGetHeader(String headerData) {
        this.utility.addGetHeader(headerData);
    }

    public void setWaitMessage(String msgText) {
        if (!msgText.equals(""))
            msgText = "\n" + msgText;
        this._messageText = _messageText + msgText;
    }


    @Override
    protected void onPreExecute() {
        if (_showProgressDialog) {
            Dialog.setMessage(this._messageText);
            Dialog.setCancelable(false);
            Dialog.setCanceledOnTouchOutside(false);
            Dialog.show();
        }
    }

    @Override
    protected String doInBackground(Void... params) {
        try {
            String result = "";
            lock.lockInterruptibly();
            do {                
                if (!Utilities.isNetworkAvailable(mContext))
                    result = "No network available";
                else if (this.type.equals("get"))
                    result = utility.doGetRequest();
                else
                    result = utility.doPostRequest();

                publishProgress(result);
                tryAgain.await();

            } while (!finished);

            lock.unlock();
            return result;
        } catch (MediCorporateException tex) {            

            if (listener != null) {
                if (isActivity) {
                        ((Activity) mContext).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.OnHttpRequestError();
                            }
                        });
                    } 
                } else {                   
                        ((GcmIntentService) mContext).runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.OnHttpRequestError();
                            }
                        });
                    } 
                }
            }
            Utilities.callCrashReport(mContext, tex);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }finally {
            lock.unlock();
        }
        return "";
    }

    @Override
    protected void onProgressUpdate(String... values) {
        if (this.listener != null) {
            if(values.length > 0) {
                if (!Utilities.isNullOrEmpty(values[0])) {
                    listener.OnHttpRequestCompleted(values[0]);
                    terminateTask();
                } else {                   
                    runAgain();
                }
            }else {
                runAgain();
            }
        }
        Log.i("Exit ", "onProgressUpdate");
    }

    public void runAgain() {
        // Call this to request data from the server again
        tryAgain.signal();
    }

    public void terminateTask() {
        // The task will only finish when we call this method
        if (_showProgressDialog)
            this.Dialog.dismiss();
        finished = true;
        if(lock.isHeldByCurrentThread())
        {
            lock.unlock();
        }
    }

    @Override
    protected void onPostExecute(String Result) {      
        Log.i("Exit ", "onPostExecute");
    }
}

Когда я получил пустой ответ от WebService, я вызвал runAgain(), и приложение распалось. Пожалуйста, дайте любое решение для устранения этого исключения.

Ответ 1

Вы должны получить блокировку, связанную с условием перед сигналом вызова.

public void runAgain() {
    // Call this to request data from the server again
    lock.lock();
    try {
        tryAgain.signal();
    } finally {
        lock.unlock();
    }
}

Решение, на которое вы ссылаетесь, имеет собственную ошибку.

Ниже скопировано из Справочник по API Android.

Рекомендации по внедрению

Реализация может (и обычно) требовать, чтобы текущий поток удерживал блокировку, связанную с этим Условием при вызове этого метода. Реализации должны документировать это предварительное условие и любые действия, предпринятые, если блокировка не удерживается. Как правило, исключается исключение, такое как IllegalMonitorStateException.

Если задание должно выполняться несколько раз, Thread, Handler или Service могут быть лучшим выбором, чем AsyncTask.