Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Case Analysis of Java Thread synchronization problem

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains the "Java thread synchronization problem case analysis", the content of the article is simple and clear, easy to learn and understand, now please follow the editor's train of thought slowly in depth, together to study and learn "Java thread synchronization problem case analysis"!

1. Scene

There are five silent philosophers sitting around a round table who have been eating and thinking all their lives.

There are five chopsticks for them to use. Philosophers need to get a pair of chopsticks with both hands before they can eat; after eating, they will put down the chopsticks and continue to think.

So now there is a problem, we need to come up with a plan, how to ensure that philosophers can eat and think alternately without starving to death.

The above question is a classic thread synchronization problem raised by Dijkstra.

two。 Solution

Before we start thinking about how to solve the problem, we can restore this scenario through code and model it in the program.

Each chopstick can be seen as a resource data, can be attempted by philosophers on both sides of it, and can only be held by one of them at a time, which can be expressed by the semaphore Semaphore in our JUC package.

Then, each philosopher can be thought of as a thread, and the content of the run method in each thread is to think first, then try to get the chopsticks on the left and right to eat, and then continue to think after the meal.

Through the above analysis, our code implementation is as follows:

/ * * @ author Blackie said Java * @ ClassName DiningPhilosophers * @ Description philosopher dining problem * @ date 2022-2-6 * * / @ Slf4jpublic class DiningPhilosophers implements Runnable {private final int id; public DiningPhilosophers (int id) {this.id = id;} private static final Random random = new Random (System.currentTimeMillis ()); private static final Semaphore [] forks = new Semaphore [5] / / initialize semaphores. Each semaphore is 1, representing a chopstick static {forks [0] = new Semaphore (1); forks [1] = new Semaphore (1); forks [2] = new Semaphore (1); forks [3] = new Semaphore (1); forks [4] = new Semaphore (1) } @ Override public void run () {try {while (true) {think (); eat (id);}} catch (InterruptedException e) {log.error ("abnormal interrupt", e) }} / * philosophers think about random time * / private void think () throws InterruptedException {TimeUnit.MILLISECONDS.sleep (random.nextInt);} private void eat (int id) {/ / TODO}}

Next, let's think about how to realize the logic of philosophers eating.

When a philosopher needs to eat, he picks up chopsticks on the left and right sides.

So:

Philosopher A (0) needs chopsticks 0 and 4

Philosopher B (1) needs chopsticks 1 and 0

Philosopher C (2) needs chopsticks 2 and 1

Philosopher D (3) needs chopsticks 3 and 2

Philosopher E (4) needs chopsticks 4 and 3

So every philosopher thread should have a number, so I defined the attribute id in DiningPhilosophers to represent the philosopher's number.

In the eating method, you need to decide which chopsticks to get according to id.

The chopsticks on the left-hand side can be expressed with fork [id]

The chopsticks on the right hand side are indicated by fork [(id+4)% 5].

Then the implementation of our eat method is as follows:

Private void eat (int id) throws InterruptedException {/ / take the chopsticks on the left [id] .acquire (); / then take the chopsticks on the right [(id + 4)% 5] .acquire (); / / have a meal log.info ("philosopher {} is eating ~", id); / / put down the chopsticks on the left and then the chopsticks on the right. Release () Forks [(id + 4) 5] .release ();}

Let's go on to test our complete code.

/ * * @ author Blackie said Java * @ ClassName DiningPhilosophers * @ Description philosopher dining problem * @ date 2022-2-6 * * / @ Slf4jpublic class DiningPhilosophers implements Runnable {private final int id; public DiningPhilosophers (int id) {this.id = id;} private static final Random random = new Random (System.currentTimeMillis ()); private static final Semaphore [] forks = new Semaphore [5] / / initialize semaphores. Each semaphore is 1, representing a chopstick static {forks [0] = new Semaphore (1); forks [1] = new Semaphore (1); forks [2] = new Semaphore (1); forks [3] = new Semaphore (1); forks [4] = new Semaphore (1) } @ Override public void run () {try {while (true) {think (); eat (id);}} catch (InterruptedException e) {log.error ("abnormal interrupt", e) }} / * philosophers think about random time * / private void think () throws InterruptedException {TimeUnit.MILLISECONDS.sleep (random.nextInt);} private void eat (int id) throws InterruptedException {/ / take the left chopstick forks [id] .acquire () / then take the chopsticks on the right forks [(id + 4)% 5] .acquire (); / / have a meal log.info ("philosopher {} is eating ~", id); / / put down the left chopsticks and the right chopsticks forks [id] .release (); forks [(id + 4)% 5] .release () } public static void main (String [] args) {for (int I = 0; I < 5; iTunes +) {new Thread (new DiningPhilosophers (I)) .start ();}

After running the above code, you will find that the program will enter a deadlock after running for a period of time.

This is because, at some point, all philosophers get the chopsticks on the left hand, but not the chopsticks on the right hand, resulting in a stalemate that no one can reach.

How to avoid this deadlock problem?

Method 1: limit the number of philosophers who eat.

A very simple way is that at a point in time, no more than four philosophers can begin to eat. If four philosophers divide five chopsticks, deadlocks will never occur.

To implement this approach, we can define another semaphore Semaphore with a permission number of 4, indicating the number of philosophers left to eat.

The code is implemented as follows:

/ * * @ author Blackie said Java * @ ClassName DiningPhilosophers * @ Description Philosopher Dining problem * @ date 2022-2-6 * * / @ Slf4jpublic class DiningPhilosophers implements Runnable {private final int id; public DiningPhilosophers (int id) {this.id = id;} private static final Random random = new Random (System.currentTimeMillis ()); private static final Semaphore [] forks = new Semaphore [5]; private static final Semaphore maxDiners = new Semaphore (4) / / initialize semaphores. Each semaphore is 1, representing a chopstick static {forks [0] = new Semaphore (1); forks [1] = new Semaphore (1); forks [2] = new Semaphore (1); forks [3] = new Semaphore (1); forks [4] = new Semaphore (1) } @ Override public void run () {try {while (true) {think (); eat (id);}} catch (InterruptedException e) {log.error ("abnormal interrupt", e) }} / * philosophers think about random time * / private void think () throws InterruptedException {TimeUnit.MILLISECONDS.sleep (random.nextInt (100));} private void eat (int id) throws InterruptedException {/ / get the meal quota first maxDiners.acquire (); / / take the chopsticks on the left [id] .acquire () / then take the chopsticks on the right forks [(id + 4)% 5] .acquire (); / / have a meal log.info ("philosopher {} is eating ~", id); / / put down the left chopsticks and the right chopsticks forks [id] .release (); forks [(id + 4)% 5] .release () / / return the quota after eating maxDiners.release ();} public static void main (String [] args) {for (int I = 0; I < 5; iTunes +) {new Thread (new DiningPhilosophers (I)). Start ();}} method 2: find a left-handed philosopher

This method is to make one of the philosophers and other philosophers hold chopsticks in a different order than other philosophers.

For example, other people take the right hand first and then the left hand, while the left-handed philosopher takes the left hand first and then the right hand.

It doesn't matter which philosopher is chosen as left-handed, because the table is round, so we choose philosopher 0 as left-handed.

The code is implemented as follows:

/ * * @ ClassName DiningPhilosophers * @ Description Philosopher Dining question * @ date 2022-2-6 * * / @ Slf4jpublic class DiningPhilosophers implements Runnable {private final int id; public DiningPhilosophers (int id) {this.id = id;} private static final Random random = new Random (System.currentTimeMillis ()); private static final Semaphore [] forks = new Semaphore [5] / / initialize semaphores. Each semaphore is 1, representing a chopstick static {forks [0] = new Semaphore (1); forks [1] = new Semaphore (1); forks [2] = new Semaphore (1); forks [3] = new Semaphore (1); forks [4] = new Semaphore (1) } @ Override public void run () {try {while (true) {think (); eat (id);}} catch (InterruptedException e) {log.error ("abnormal interrupt", e) Philosophers think about Random time * / private void think () throws InterruptedException {TimeUnit.MILLISECONDS.sleep (random.nextInt);} private void eat (int id) throws InterruptedException {if (id = = 0) {hanleLeftFirst (id);} else {hanldRightFirst (id) Log.info ("philosopher {} is eating ~", id); forks [(id + 4)% 5] .release ();} private void hanleLeftFirst (int id) throws InterruptedException {forks [id] .acquire (); forks [(id + 4)% 5] .acquire () } private void hanldRightFirst (int id) throws InterruptedException {forks [(id + 4)% 5] .acquire (); Forks [id] .acquire ();} public static void main (String [] args) {for (int I = 0; I < 5; iTunes +) {new Thread (new DiningPhilosophers (I)) .acquire () Thank you for your reading. The above is the content of "Java thread synchronization problem example analysis". After the study of this article, I believe you have a deeper understanding of Java thread synchronization problem example analysis. the specific use also needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report