-
Notifications
You must be signed in to change notification settings - Fork 753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The way to finish a thread in volley. #60
Comments
你为啥想要单独停止一个volley线程?? |
I agree it seems strange that we use a separate mQuit flag rather than just relying on the interrupt status. I don't see why you'd want to interrupt the threads but continue to have them pull ensuing requests off the queue. So I could get behind a change which does what you describe and uses the interrupt status directly rather than relying on a separate mQuit flag. |
I agree that this looks fishy, but is there really a problem in practice? It would be great to have unit tests before making subtle changes. Concerning the proper way to improve this, consider:
These are reasons to maintain a dedicated cancellation flag and to check this flag inside the loop:
Speaking of catching InterruptedException without reasserting the interrupt flag, note that standard practice is to reassert the interrupt flag before continuing:
Arguably, this may not be useful here, as a thread stops running after returning from run()... OTOH, these are public Thread subclasses so without further analysis one can imagine they may themselves be subclassed or executed in surprising ways. |
Personally this feels like a minor concern because in practice, RequestQueue always starts threads immediately after creating them. You'd have to be doing something very custom with your queue or somehow manually be using CacheDispatcher/NetworkDispatcher outside the scope of a RequestQueue for this to be a potential issue, right?
These are bugs that should be fixed (so long as they are happening in NetworkDispatcher/CacheDispatcher). This is a common mistake but usually a bug nonetheless, and certainly we should audit those classes for situations where this happens before moving to relying on the interrupted flag entirely. |
My main concern is the fragility of the Thread.interrupt flag. Given that this is a public Thread class, I think a dedicated private flag is a good idea. It clearly indicates that quit() was called and it will not be cleared according to the whim of some other code executing on this thread. |
i have a question.why does volley use thread array but not Executor? |
Yeah, I can admit that getting interrupt right is hard (primary evidence being all the places in Volley that get it wrong), and that unfortunately with these classes being public / extensible we can't really control what code runs on them. Maybe it's best to just leave things the way they are here. Re: thread array vs. Executor - what would an Executor allow us to do better? (This dates back to the beginning of Volley AFAIK, so I don't really know why it was done this way, but I also don't know that there's much reason to change it...) |
interrupts. Volley relies on a quit() method and mQuit flag on both dispatcher threads to shut down those threads. These could just use the interrupt state instead, but as noted on google#60, these are public, non-final classes, and so relying on interrupt depends on external callers and subclasses using the interrupt state correctly. To be more conservative and retain existing behavior, we keep the quit method/flag around to ensure that we only shut down the dispatchers when quit() is called. However, we re-raise the interrupt flag in this case. If we're interrupted outside of quit(), we suppress the interrupt flag and log a warning instead. Fixes google#60
interrupts. Volley relies on a quit() method and mQuit flag on both dispatcher threads to shut down those threads. These could just use the interrupt state instead, but as noted on #60, these are public, non-final classes, and so relying on interrupt depends on external callers and subclasses using the interrupt state correctly. To be more conservative and retain existing behavior, we keep the quit method/flag around to ensure that we only shut down the dispatchers when quit() is called. However, we re-raise the interrupt flag in this case. If we're interrupted outside of quit(), we suppress the interrupt flag and log a warning instead. Fixes #60
In volley, to finish a thread such as CacheDiapatcher and NetworkDispatcher, are inturrupt not enough? Whether need the mQuit variable necessarily.
If write like this, hava any problems? those thread can be interrupted in other scenes?
public void quit() { interrupt(); }
while (!isInterrupted()) { ................... try { request = mQueue.take(); } catch (InterruptedException e) { return; } }
The text was updated successfully, but these errors were encountered: