What is a deadlock, and how can we creatively solve it

Overview
Have you ever experienced a stalemate in a meeting, project, or negotiation where progress seems impossible because everyone waits for someone else to make the first move? You’ve just walked into a deadlock, a common scenario in computer science and everyday life.
In this article, I will cover what a deadlock is, the different scenarios it can take, and three common strategies to resolve/avoid it.
By taking and applying technical patterns to deal with deadlocks in our everyday life, we can creatively solve problems and better deal with complex situations.
What is a deadlock?
Imagine two computer programs, each waiting for the other to release a piece of information they need to proceed. Neither can move forward, creating a standstill.
In more technical terms, a deadlock refers to a situation where two or more processes cannot proceed. Each waits for the other to release a necessary resource, creating a circular chain of dependencies.
Let’s see a simplified example. The Purchase service tries to charge with the Finance service, which checks for available funds from the Balance service and checks for open charges in the Purchase service.
All the services wait for another service to complete an operation that cannot be completed due to a chain of dependency.
Now that we understand what a deadlock is in computer science let’s look at examples of how this concept can appear in our everyday lives.
Are there deadlocks in real life?
Sure! Here are three scenarios illustrating how a deadlock looks in real-life applications.
Feature dependency
Let’s say we have a new feature to add a “recommended for you” area after making a purchase. There are a few teams involved -
Data science — to create the recommendation model
Retention — to provide the necessary backend logic to decide which recommendations should be shown to which segments.
Checkout — to show the recommendations engagingly through the user journey in the checkout application.
The Data science team cannot proceed without accurate data on customer affinity, which is expected to come from the Retention team’s backend logic. However, the Retention team cannot provide this data without the Checkout team's integration, which is waiting for the Data Science team to create the recommendation model. Thus, all units are in a deadlock, waiting on each other to proceed.
Contract negotiation
Company A is negotiating with Company B to provide its services with an online product. Company B won’t sign the contract until Company A improves product quality and features. But Company A won’t make those improvements without a signed contract from Company B.
Product development
A Product team is developing a new product as part of an MVP and collaborates with the Marketing team to build the go-to-market strategy. The Product team hesitates to finalize the feature set without additional market discovery steps, while the Marketing team can’t complete their plan without knowledge of the final features.
That’s a real problem!
In these scenarios, we see a deadlock: each team or party waits for another to act before proceeding, causing all to be stuck.
So, how can we break these deadlocks? In the world of software development, there are specific patterns used to tackle deadlocks. Let’s explore how these can be applied to our real-life scenarios.
How to deal with deadlocks?
Let’s explore three patterns to deal with deadlocks in software applications and try applying them to the scenarios above.
Timeouts
In each scenario, we have a process that waits for a resource (e.g., company B waits for a higher-quality product). Timeout is a straightforward way to avoid deadlocks by settings the maximum time to wait for a resource. After that, the process either ends or flags an issue and attempts to move on.
Let’s apply it to the contract negotiation scenario. The two companies could decide on a shared timeout of, let’s say, 30 days. As neither company is willing to make the first move, each commits to complete a small task within the more extensive process.
Company A might commit to providing a plan for quality improvement. In contrast, company B will commit to finalizing the contract and getting internal approval. If, by 30 days, the milestone has yet to be reached, the contract will not be signed.
Setting timeouts and defining intermediate milestones enables the companies to break the deadlock.
Wait-Die/Wound-Wait
This algorithm offers a way to avoid deadlocks by settings priority based on the age of the request — the older the request, the higher its priority. Imagine you’re in line for a famous ride at an amusement park, and people keep getting in line in front of each other. Without diving into details, the two algorithms suggest ensuring the line won’t get stuck.
Inspired by that, let’s return to the Product Development example and say our company procedures prioritize the team that started their work first. If the Product Team started working on their feature set (resource) first, then according to our policy, they get priority.
The Marketing team would have to wait for them to finish before they can start on the market positioning (another resource). Once the positioning is provided, the Product Team might want to adjust the feature set and vice versa.
In this example, we set strict rules to avoid deadlock by enforcing an age-based priority between teams.
Two-Phase Locking (2PL)
Usually used in concurrent systems (like databases), the 2PL protocol is divided into the Lock phase (where the process gathers all the required resources and locks them) and the Release phase (where it releases all the resources before acquiring new ones).
Let’s see it in action with our Feature Dependency scenario. Each team would identify the tasks it can work on that don’t need resources from other teams (Lock phase). For example, the Data Science team could build the model based on historical data, while the Checkout team could build the UX using mock data.
Once a team needs to collaborate with another team (Release phase), it frees up the resource (for example, a UX mockup or a model based on historical data), allowing other teams to continue to the next set of tasks.
Using the Two-Phase Locking protocol enables dependency teams to move in parallel and avoid the deadlock in the first place.
Summary
In this article, we navigated the concept of deadlock in computer science and real-life situations such as product development and contract negotiations.
We discovered that deadlocks can be unraveled and mitigated using strategies from software applications, like timeouts, wait-die/wound-wait, and two-phase locking.
Hence, understanding and strategically applying these patterns can guide us to efficient problem-solving in various deadlock scenarios.