diff --git a/second-edition/dictionary.txt b/second-edition/dictionary.txt
index 3f2c8f43a..f5b416ea9 100644
--- a/second-edition/dictionary.txt
+++ b/second-edition/dictionary.txt
@@ -228,6 +228,7 @@ lifecycle
LimitTracker
lobally
locators
+LockResult
login
lookup
loopback
diff --git a/second-edition/src/ch20-05-sending-requests-via-channels.md b/second-edition/src/ch20-05-sending-requests-via-channels.md
index a957bfd4f..1532b0d42 100644
--- a/second-edition/src/ch20-05-sending-requests-via-channels.md
+++ b/second-edition/src/ch20-05-sending-requests-via-channels.md
@@ -498,6 +498,52 @@ never create more than four threads, so our system won’t get overloaded if the
server gets a lot of requests. If we make a request to `/sleep`, the server
will be able to serve other requests by having another thread run them.
+After learning about the `while let` loop in Chapter 18, you might be
+wondering why we didn't write the worker thread like this:
+
+Filename: src/lib.rs
+
+```rust,ignore
+// ...snip...
+
+impl Worker {
+ fn new(id: usize, receiver: Arc>>) -> Worker {
+ let thread = thread::spawn(move || {
+ while let Ok(job) = receiver.lock().unwrap().recv() {
+ println!("Worker {} got a job; executing.", id);
+
+ job.call_box();
+ }
+ });
+
+ Worker {
+ id,
+ thread,
+ }
+ }
+}
+```
+
+Listing 20-22: An alternative implementation of the worker
+thread using `while let`
+
+This code compiles and runs, but doesn't result in the desired threading
+behavior. The reason why is somewhat subtle: the `Mutex` struct has no public
+`unlock` method because the ownership of the lock is based on the lifetime of
+the `MutexGuard` within the `LockResult>` that `lock` returns.
+This allows the borrow checker to enforce at compile time that we never access
+a resource guarded by a `Mutex` without holding the lock, but it can also result
+in holding the lock longer than intended if you don't think carefully about
+the lifetime of the `MutexGuard`. Since the values in the the `while`
+expression remain in scope for the duration of the following block, the lock
+remains held for the duration of the call to `job.call_box()`, meaning other
+workers cannot receive jobs.
+
+By using `loop` instead, the `MutexGuard` is dropped as soon as the `let job`
+statement ends. This ensures that the lock is held during the call to `recv`,
+but it is released before the call to `job.call_box()`, allowing multiple
+requests to be serviced concurrently.
+
What about those warnings, though? Don’t we use the `workers`, `id`, and
`thread` fields? Well, right now, we’re using all three of these fields to hold
onto some data, but we don’t actually *do* anything with the data once we’ve