您的位置:首页 > 其它

多线程--哲学家就餐问题

2015-07-05 20:06 337 查看


1、当哲学家的左右筷子均是可用的时候才能就餐,否则等待,很容易理解,一次最多能有两个人同时就餐

public class PhilosopherEating
{
private static Thread[] threads = new Thread[5];
public static void main(String[] args)
{
System.out.println("Hello World!");
for(int i = 0 ; i < 5; i ++){
threads[i] = new Thread(new Philosopher(i));
threads[i].start();
}
//当前线程组活动线程数
while(Thread.activeCount()>1){
Chopstick.monitor();
try{
Thread.sleep(1000);
}catch(InterruptedException ex){

}
}
}
}
/*
*   哲学家进程
*/
class Philosopher implements Runnable
{
//所有哲学家共用五支筷子
private static Chopstick chopstick = new Chopstick();

//哲学家编号
private int id = 0;

public Philosopher(int id){
this.id = id;
}

public void run(){
while(true){
if(new Random().nextBoolean()){
//取筷子
chopstick.take(id);
eat();
//放筷子
chopstick.down(id);

}else{
think();
}
}
}
//就餐
private void eat(){
int time = new Random().nextInt(10);
try{
System.out.println(id + "就餐"+time+"s");
Thread.sleep(time*1000);
System.out.println(id + "就餐完成!");
}catch(InterruptedException ex){
System.out.println("ex:eat");
}
}
//思考
private void think(){
int time = new Random().nextInt(10);
try{
System.out.println(id + "思考"+time+"s");
Thread.sleep(time*1000);
}catch(InterruptedException ex){
System.out.println("ex:think");
}
}

}
/*
*   筷子
*   作为资源
*/
class Chopstick
{
private static Lock lock = new ReentrantLock();
private static Condition chopstick = lock.newCondition();

//五支筷子是否在使用
private static boolean[] used = new boolean[5];

//取筷子
public void take(int id){
//获取锁
lock.lock();
try{
//左筷子,右筷子可以使用
while(used[id] || used[(id+1)%5]){
chopstick.await();
}
used[id] = true;
used[(id+1)%5] = true;
}catch(InterruptedException ex){

}finally{
//释放锁
lock.unlock();
}
}
//放筷子
public void down(int id){
lock.lock();
used[id] = false;
used[(id+1)%5] = false;
chopstick.signalAll();
lock.unlock();
}
//监控是否发生死锁,如果所有的筷子都是使用状态,则说明死锁
public static boolean monitor(){
boolean flag = true;
for(int i = 0 ; i < 5 ; i ++ ){
if(used[i] == false){
flag = false;
break;
}
}
return flag;
}
}


2、创建一个服务员,每次哲学家就餐都需要询问服务员

public class PhilosopherEating2
{
private static Thread[] threads = new Thread[5];
public static void main(String[] args)
{
System.out.println("Hello World!");
for(int i = 0 ; i < 5; i ++){
threads[i] = new Thread(new Philosopher(i));
threads[i].start();
}
//当前线程组活动线程数
while(Thread.activeCount()>1){
if(Waiter.monitor()){
System.out.println("死锁!!!!!!!!!!!!!!!!");
}
try{
Thread.sleep(100);
}catch(InterruptedException ex){

}
}
}
}
/*
*   哲学家进程
*/
class Philosopher implements Runnable
{
//服务员
private static Waiter waiter = new Waiter();

//哲学家编号
private int id = 0;

public Philosopher(int id){
this.id = id;
}

public void run(){
while(true){
if(new Random().nextBoolean()){
if(waiter.ask(id)){
eat();
waiter.put(id);
}
}else{
think();
}
}
}
//就餐
private void eat(){
int time = new Random().nextInt(10);
try{
System.out.println(id + "就餐"+time+"s");
Thread.sleep(time*100);
System.out.println(id + "就餐完成!");
}catch(InterruptedException ex){
System.out.println("ex:eat");
}
}
//思考
private void think(){
int time = new Random().nextInt(10);
try{
System.out.println(id + "思考"+time+"s");
Thread.sleep(time*100);
}catch(InterruptedException ex){
System.out.println("ex:think");
}
}

}

/*
*   服务员
*/
class Waiter
{
//五支筷子是否在使用
private static boolean[] used = new boolean[5];

//询问是否可以就餐
public synchronized boolean ask(int id){
if(used[id] || used[(id+1)%5]){
return false;
}
used[id] = true;
used[(id+1)%5] = true;
return true;
}
//交筷子
public synchronized void put(int id){

used[id] = false;
used[(id+1)%5] = false;

}
//监控是否发生死锁,如果所有的筷子都是使用状态,则说明死锁
public static boolean monitor(){
boolean flag = true;
for(int i = 0 ; i < 5 ; i ++ ){
if(used[i] == false){
flag = false;
break;
}
}
return flag;
}
}


3、使用信号量,每个哲学家只能先申请大号筷子,然后再申请小号筷子,即使是4号哲学家,也只能是先申请4号筷子,然后再申请0号筷子

public class PhilosopherEating3
{
private static Thread[] threads = new Thread[5];
public static void main(String[] args)
{
System.out.println("Hello World!");
for(int i = 0 ; i < 5; i ++){
threads[i] = new Thread(new Philosopher(i));
threads[i].start();
}
//当前线程组活动线程数
while(Thread.activeCount()>1){
int count = 0;
for(int i = 0 ; i < 5; i ++){
if(threads[i].getState().equals(Thread.State.BLOCKED)){
count++;
}
}
if(count == 5){
System.out.println("死锁!!!!!!!!");
for(int i = 0 ; i < 5; i ++ ){
System.out.println(threads[i].getState());
}
}
try{
Thread.sleep(1000);
}catch(InterruptedException ex){

}
}
}
}
/*
*   哲学家进程
*/
class Philosopher implements Runnable
{
//所有哲学家共用五支筷子
private static Chopstick chopstick = new Chopstick();

//哲学家编号
private int id = 0;

public Philosopher(int id){
this.id = id;
}

public void run(){
while(true){
if(new Random().nextBoolean()){
//取筷子
chopstick.take(id);
eat();
//放筷子
chopstick.down(id);

}else{
think();
}
}
}
//就餐
private void eat(){
int time = new Random().nextInt(10);
try{
System.out.println(id + "就餐"+time+"s");
Thread.sleep(time*100);
System.out.println(id + "就餐完成!");
}catch(InterruptedException ex){
System.out.println("ex:eat");
}
}
//思考
private void think(){
int time = new Random().nextInt(10);
try{
System.out.println(id + "思考"+time+"s");
Thread.sleep(time*100);
}catch(InterruptedException ex){
System.out.println("ex:think");
}
}

}
/*
*   筷子
*   作为资源
*/
class Chopstick
{

//五支筷子资源
private static Semaphore[] used = new Semaphore[5];

public Chopstick(){
for(int i = 0; i < 5; i ++){
used[i] = new Semaphore(1);
}
}
//取筷子
public void take(int id){
//获取锁
try{
if(id < 4){
//先申请号大的筷子
used[id+1].acquire();
//申请号小的筷子
used[id].acquire();
}else{
//id = 4时比较特殊
//先申请号大的筷子
used[id].acquire();
//申请号小的筷子
used[0].acquire();
}
}catch(InterruptedException ex){

}finally{

}
}
//放筷子
public void down(int id){
//先释放小号,再释放大号
if(id < 4){
used[id].release();
used[id+1].release();
}else{
//id = 4时比较特殊
used[0].release();
used[id].release();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: