生产者消费者,哲学家就餐------java(synchronized,wait,notify)

本文通过两个经典的多线程同步问题——生产者消费者模型和哲学家就餐问题,介绍了如何利用Java语言实现线程间的同步操作。生产者消费者模型展示了如何在生产者和消费者之间共享资源并协调工作;哲学家就餐问题则通过解决死锁问题,展现了如何让多个线程(哲学家)在共享资源(筷子)的情况下正常运行。

一  生产者消费者

package com.java.ly2011.Semptember;

import java.util.ArrayList;
import java.util.List;

public class ProducerConsumer {
 
 public static void main(String[] args) {
  
  List basket = new ArrayList();
  
  Producer producer1 = new Producer(basket);
  Consumer consumer1 = new Consumer(basket);
  
  new Thread(producer1).start();
  new Thread(consumer1).start();
  
  
 }
 
}

class Producer implements Runnable{
 
 private List basket;
 
 private int basketLimit=5;
 
 public Producer(List basket){
  this.basket = basket;
 }
 
 @Override
 public void run() {
  // TODO Auto-generated method stub
  while(true){
   try {
    Thread.sleep(3000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   pruduce(basket);
  }
  
 }
 
 public void pruduce(List basket){
  synchronized (basket) {
   while(basket.size()==basketLimit){
    
    System.out.println("basket is full");
    try {
     basket.wait();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   }
   basket.add(basket.size()+1);
   System.out.println("put " +basket.size());
   basket.notifyAll();
  }
  
 }
 
}

class Consumer implements Runnable{

 private List basket;
 
 public Consumer(List basket){
  this.basket = basket;
 }
 
 @Override
 public void run() {
  // TODO Auto-generated method stub
  while(true){
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   consume(basket);
  }
 }
 
 public void consume(List basket){
  
  synchronized (basket) {
   
   while(basket.size()==0){
    
    System.out.println("the bask is empty");
    try {
     basket.wait();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   }
   System.out.println("get "+basket.get(basket.size()-1));
   basket.remove(basket.size()-1);
   basket.notifyAll();
  }
  
 }
 
 
 
}

二 哲学家就餐

package com.java.ly2011.Semptember;

import java.util.Date;

public class PhilosopherEat {
 public static void main(String[] args) {
  
  KZ k1 = new KZ(1);
  KZ k2 = new KZ(2);
  KZ k3 = new KZ(3);
  KZ k4 = new KZ(4);
  KZ k5 = new KZ(5);
  
  People p1 = new People("Pone", k1, k2);
  People p2 = new People("Ptwo", k2, k3);
  People p3 = new People("Pthree", k3, k4);
  People p4 = new People("Pfour", k4, k5);
  People p5 = new People("Pfive", k5, k1);
  
  Thread p1Thread = new Thread(p1);
  Thread p2Thread = new Thread(p2);
  Thread p3Thread = new Thread(p3);
  Thread p4Thread = new Thread(p4);
  Thread p5Thread = new Thread(p5);
  
  
  p1Thread.start();
  p4Thread.start();
  p3Thread.start();
  p2Thread.start();
  p5Thread.start();
  
  
  

 }
}

/**
 * KZ本身不能做任何事情,属于它的只有名字和使用状态
 * @author liuyang
 *
 */
class KZ{
 private int id;
 private boolean status=true;//true 代表可用   false代表不可用
 //boolean类型的成员变量的默认值是false
 
 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public boolean isStatus() {
  return status;
 }

 public void setStatus(boolean status) {
  this.status = status;
 }
 
 public KZ(int id){
  this.id = id;
 }

 @Override
 public String toString() {
  // TODO Auto-generated method stub
  return "i am KZ " + id;
 }
}

class People implements Runnable{
 
 private String name;
 
 private KZ leftKZ;
 
 private KZ rightKZ; 
 
 
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public KZ getLeftKZ() {
  return leftKZ;
 }

 public void setLeftKZ(KZ leftKZ) {
  this.leftKZ = leftKZ;
 }

 public KZ getRightKZ() {
  return rightKZ;
 }

 public void setRightKZ(KZ rightKZ) {
  this.rightKZ = rightKZ;
 }

 /**
  *
  * @param name
  * @param lefKz
  * @param rigKz
  */
 public People(String name , KZ leftKz , KZ rightKz){
  this.name = name;
  this.leftKZ = leftKz;
  this.rightKZ = rightKz;
 }
 
 /**
  * 人可以拿KZ  
  * @param kz
  */
  public void pickUp(KZ kz){
   synchronized(kz){
   //放弃锁的条件是这个KZ已经不可用了false,我拿不了了,放弃锁,我以及别人都可以进到下面wait()着
   while(kz.isStatus()==false){
    try {
     System.out.println(this.getName() + " is waiting for kz"+kz.getId());
     kz.wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   //可以用,我用了,把它设成false别人不能用只能等
   kz.setStatus(false);
   System.out.println("-----kz" +kz.getId() + " is picked up by " +this.getName());
   }
 }
 
 /**
  * 人也可以放下KZ
  * @param kz
  */
  public void putDown(KZ kz){
   synchronized(kz){
   
   kz.setStatus(true);
   //放下后,同意其他人可以用了
   kz.notifyAll();
   System.out.println("-----kz" +kz.getId() + " is put down by " +this.getName());
   
   //故意这么做,因为notify之后并不是立即释放锁,而是synchronized语句块结束后才释放锁
   try {
    Thread.sleep(50);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
   }
 }
 

 @Override
 public void run() {
  //run就代表开始要吃了
  
  pickUp(leftKZ);//拿左
  pickUp(rightKZ);//拿又
  
  System.out.println(name +" begin to eat.  time:" +new Date());
  //////////////////////////////////////////
  try {
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  /////////////////////////////////////////
  System.out.println(name + " end  to eat.  time:" +new Date());
  
  putDown(leftKZ);//放左
  putDown(rightKZ);//放又
  
 }
 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值