求教多线程哲学家就餐问题~~~

有点方, 2021-06-29 18:43:15

为什么运行时只有135或者024能够吃饭呢??救救孩子吧 想了一天了~~~~

public class Cutlery {
	    public boolean Status = false;
	    private int index;
	    Cutlery(int index) {
	    	this.index=index;		
}		
}
 
 
public class Philosopher implements Runnable{
	private int index;
	private Cutlery right; 
    private Cutlery left;
    private int thinkTime;
    public Philosopher(Cutlery right, Cutlery left, int index, int thinkingTime) {
        super();
        this.right = right;
        this.left = left;
        this.index = index;
        this.thinkTime = thinkingTime;
    }
    public void run() {
    		try {
    		while (!Thread.interrupted()) {
    	    this.thinking();
		    this.Take();
            this.eating();
            this.Drop() ;
            System.out.println("Philosopher["+index+"]"+"put down his cutlery");}
    }catch (InterruptedException e) {
		e.printStackTrace();}
	}
    public synchronized void Take()throws InterruptedException{
    	while(right.Status||left.Status) {
    		wait();
    	}
    	right.Status=true;
    	left.Status=true;
    }
    public synchronized void Drop() {
    	right.Status=false;
    	left.Status=false;
    	notifyAll();
    }
    public synchronized void thinking(){
    	System.out.println("Philosopher["+index+"]"+"is thinking");
		try {
			Thread.sleep(thinkTime);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
    public synchronized void eating(){
    	System.out.println("Philosopher["+index+"]"+"Pick up the cutlery and start eating");
		try {
			Thread.sleep(thinkTime);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
 
 
}
 
 
public class Text {
		public static void main(String args[]){
			Cutlery[] cutlery=new Cutlery[6];
			Philosopher[] philosopher=new Philosopher[6];
			for(int i=0;i<6;i++) {
				cutlery[i]=new Cutlery(i);
			}
			for(int i=0;i<6;i++) {
				philosopher[i]=new Philosopher(cutlery[i], cutlery[(i+1)%6],i,500);
			}
			new Thread(philosopher[0],"0").start();
			new Thread(philosopher[1],"1").start();
			new Thread(philosopher[2],"2").start();
			new Thread(philosopher[3],"3").start();
			new Thread(philosopher[4],"4").start();
			new Thread(philosopher[5],"5").start();
		}
 
	
	
}

 

...全文
674 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
老王就是我 2021-06-30
  • 打赏
  • 举报
回复

加锁的地方错了,sync 方法(),是指,同一时间只会有一个线程能进入该方法

=PNZ=BeijingL 2021-06-30
  • 打赏
  • 举报
回复 1

“不懂 能帮忙修改下吗”

简单说就是:多个线程必须访问同一个对象的方法, 这个方法上加锁 ,没有获取锁的线程才会等待, 同理多线程处理同一个对象的某个方法进入wait , 这个对象nofityall 唤醒这个对象上进入wait状态的线程

简单写了下你的问题处理方式,具体实现效果你自己修改吧, 因为我没有明白你代码里左边右边状态判断要实现什么效果 处理方法就是把你的这些行为都封装到一个action对象上, 所有线程共持有同一个对象 ,action对象notifyall唤醒其上wait的线程

public class Cutlery {
    public boolean Status = false;
    private int index;

    Cutlery(int index) {
        this.index = index;
    }
}

public class Philosopher implements Runnable {
    private int index;
    private Cutlery right;
    private Cutlery left;
    private int thinkTime;
    Action action;

    public Philosopher(Cutlery right, Cutlery left, int index,Action action) {
        super();
        this.right = right;
        this.left = left;
        this.index = index;
        this.action=action;
    }

    public void run() {
        try {
            while (!Thread.interrupted()) {
                action.thinking(right,left,index);
                action.Take(right,left,index);
                action.eating(right,left,index);
                action.Drop(right,left,index);
                System.out.println("Philosopher[" + index + "]"
                        + "put down his cutlery");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

package com.star.sms.business.armgmt;

public class Action {

    public synchronized void Take(Cutlery right, Cutlery left, int index)
            throws InterruptedException {
        while (right.Status || left.Status) {
            wait();
        }
        right.Status = true;
        left.Status = true;
    }

    public synchronized void Drop(Cutlery right, Cutlery left, int index) {
        System.out.println("Philosopher[" + index + "]" + "Drop");
        right.Status = false;
        left.Status = false;
        notifyAll();
    }

    public synchronized void thinking(Cutlery right, Cutlery left, int index) {
        System.out.println("Philosopher[" + index + "]" + "is thinking");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void eating(Cutlery right, Cutlery left, int index) {
        System.out.println("Philosopher[" + index + "]"
                + "Pick up the cutlery and start eating");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test {
    public static void main(String args[]) {
        Cutlery[] cutlery = new Cutlery[6];
        Philosopher[] philosopher = new Philosopher[6];
        for (int i = 0; i < 6; i++) {
            cutlery[i] = new Cutlery(i);
        }
        Action action=new Action();
        for(int i=0;i<6;i++) {
            philosopher[i]=new Philosopher(cutlery[i], cutlery[(i+1)%6],i,action);
        }
        new Thread(philosopher[0],"0").start();
        new Thread(philosopher[1],"1").start();
        new Thread(philosopher[2],"2").start();
        new Thread(philosopher[3],"3").start();
        new Thread(philosopher[4],"4").start();
        new Thread(philosopher[5],"5").start();

    }

}
有点方, 2021-06-30
  • 举报
回复
@=PNZ=BeijingL 懂了 感谢~
=PNZ=BeijingL 2021-06-29
  • 打赏
  • 举报
回复 1

解决你的问题,你需要知道三个知识点

1. synchronized 锁再方法是是对象实例上加锁, 你的每个线程都是new Philosopher的,所以其实你的锁都没有作用

2. notifyAll(); 是唤醒正在等待此对象监视器锁的所有线程, 同样因为每个线程是new Philosopher,所以对你程序没效果

3. 另外多线程处理是随机的,并不是代码new Thread写在上面就先执行,

假设

Cutlery2 和Cutlery 3 同时执行到Take 方法

Cutlery2 ,判断2和3的Status其中一个是false ,那么足条件 修改成true,

Cutlery3, 因为另一个对象中锁不起作用,判断3和4的Status其中一个是false 那么将3和4设置成true,

这个时候,Cutlery3 完成 notifyAll 也唤醒不了Cutlery4  ,则Cutlery4永远都在Take()方法上wait

 

 

有点方, 2021-06-29
  • 举报
回复
@=PNZ=BeijingL Take方法是有一个为TRUE(状态为使用中)就进入wait,只有都是FALSE(都没在使用)才会修改3,4为TRUE
有点方, 2021-06-29
  • 举报
回复
@=PNZ=BeijingL 不懂 能帮忙修改下吗
有点方, 2021-06-29
  • 举报
回复
@=PNZ=BeijingL 就是说synchronized只能用在以及实例化的对象上吗

51,407

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧