/** * This method is called each time a Being acquires a Palantir. Since each Being is a Java Thread, * it will be called concurrently from different threads. This method increments the number of * threads gazing and checks that the number of threads gazing does not exceed the number of * Palantiri in the simulation using an AtomicLong object instantiated above (mGazingThreads). If * the number of gazing threads exceeds the number of Palantiri, this thread will call shutdown * and return false. * * @return false if the number of gazing threads is greater than the number of Palantiri, * otherwise true. */ private boolean incrementGazingCountAndCheck(PalantiriPresenter presenter) { final long numberOfGazingThreads = presenter.mGazingTasks.incrementAndGet(); if (numberOfGazingThreads > Options.instance().numberOfPalantiri()) { presenter.shutdown(); return false; } else return true; }
/** Perform the Being gazing logic. */ @Override public Void doInBackground(PalantiriPresenter... presenters) { // Don't start the threads immediately. Utils.pauseThread(500); // Initialize local variables. int i = 0; Palantir palantir = null; final PalantiriPresenter presenter = presenters[0]; // Try to gaze at a palantir the designated number of times. for (; i < Options.instance().gazingIterations(); ++i) try { // Break out of the loop if the BeingAsyncTask has // been cancelled. // you fill in here by replacing "false" with // the appropriate method call to an AsyncTask method. if (isCancelled()) { // If we've been instructed to stop gazing, notify // the UI and exit gracefully. presenter.mView.get().threadShutdown(mIndex); break; } // Show that we're waiting on the screen. // you fill in here with the appropriate // call to an AsyncTask method. publishProgress(presenter.mView.get().markWaiting(mIndex)); // Get a Palantir - this call blocks if there are no // available Palantiri. palantir = presenter.getModel().acquirePalantir(); if (palantir == null) Log.d( TAG, "Received a null palantir in " + Thread.currentThread().getId() + " for Being " + mIndex); // Make sure we were supposed to get a Palantir. if (!incrementGazingCountAndCheck(presenter)) break; // Mark it as used on the screen. // you fill in here with the appropriate // call to an AsyncTask method. publishProgress(presenter.mView.get().markUsed(palantir.getId())); // Show that we're gazing on the screen. // you fill in here with the appropriate // call to an AsyncTask method. publishProgress(presenter.mView.get().markGazing(mIndex)); // Gaze at my Palantir for the alloted time. palantir.gaze(); // Show that we're no longer gazing. // you fill in here with the appropriate // call to an AsyncTask method. publishProgress(presenter.mView.get().markIdle(mIndex)); Utils.pauseThread(500); // Mark the Palantir as being free. // you fill in here with the appropriate call // to an AsyncTask method. publishProgress(presenter.mView.get().markFree(palantir.getId())); Utils.pauseThread(500); // Tell the double-checker that we're about to // give up a Palantir. decrementGazingCount(presenter); } catch (Exception e) { Log.d(TAG, "Exception caught in index " + mIndex); // If we're interrupted by an exception, notify the UI and // exit gracefully. presenter.mView.get().threadShutdown(mIndex); } finally { // Give it back to the manager. presenter.getModel().releasePalantir(palantir); } Log.d( TAG, "Thread " + mIndex + " has finished " + i + " of its " + Options.instance().gazingIterations() + " gazing iterations"); return (Void) null; }