Philosophers in the dining problem of JAVA multithreading learning

  • 2020-04-01 02:32:57
  • OfStack

At a round table sat five philosophers, with a chopstick between them and noodles in the middle of the table. The philosopher thinks about the problem, when hungry to pick up left and right chopsticks to eat, you must get two chopsticks to eat. The above problem leads to deadlock, which occurs when all five philosophers pick up their right hand chopsticks and prepare to pick up their left hand chopsticks.

Solutions:

1, add a waiter, only after the waiter agreed to take the chopsticks, the waiter is responsible for avoiding deadlock.

2. Each philosopher must make sure that both his left and right chopsticks are available before he can eat with both and then put both down.

3, each philosopher must take the small number of chopsticks, so that the last philosopher did not get the chopsticks only the large number of the chopsticks, can not pick up, the remaining chopsticks can be used by other philosophers, to avoid deadlock. This is not a good use of resources.

Code implementation: implement the second scenario


package cn.edu.sdust.Philosopher;


class Philosopher extends Thread{
    private String name;
    private Fork fork;
    public Philosopher(String name,Fork fork){
        super(name);
        this.name=name;
        this.fork=fork;
    }

    public void run(){
        while(true){
            thinking();
            fork.takeFork();
            eating();
            fork.putFork();
        }

    }

    
    public void eating(){
        System.out.println("I am Eating:"+name);
        try {
            sleep(1000);//Simulate eating, occupy a period of time resources
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    
    public void thinking(){
        System.out.println("I am Thinking:"+name);
        try {
            sleep(1000);//Simulation of thinking
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
class Fork{
    
    private boolean[] used={false,false,false,false,false,false};

    
    public synchronized void takeFork(){
        String name = Thread.currentThread().getName();
        int i = Integer.parseInt(name);
        while(used[i]||used[(i+1)%5]){
            try {
                wait();//If one is in use, wait
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        used[i ]= true;
        used[(i+1)%5]=true;
    }

    
    public synchronized void putFork(){
        String name = Thread.currentThread().getName();
        int i = Integer.parseInt(name);

        used[i ]= false;
        used[(i+1)%5]=false;
        notifyAll();//Wake up other threads
    }
}
//test
public class ThreadTest {
    public static void main(String []args){
        Fork fork = new Fork();
        new Philosopher("0",fork).start();
        new Philosopher("1",fork).start();
        new Philosopher("2",fork).start();
        new Philosopher("3",fork).start();
        new Philosopher("4",fork).start();
    }
}

Operation results:


I am Thinking:0
I am Thinking:2
I am Thinking:3
I am Thinking:1
I am Thinking:4
I am Eating:0
I am Eating:2
I am Thinking:0
I am Eating:4
I am Thinking:2
I am Eating:1
I am Thinking:4
I am Eating:3
I am Thinking:1
I am Eating:0
I am Thinking:3
I am Eating:2
I am Thinking:0
I am Eating:4
I am Thinking:2

Analysis: the above solution solves the deadlock problem. It can be seen that there can be no more than two adjacent eating results, because at most two people can eat at the same time in each moment, and the seats of two people are not adjacent.


Related articles: