哲学家进餐问题与生产者与消费者问题(java实现)

来源:互联网 发布:德国航空发动机知乎 编辑:程序博客网 时间:2024/05/21 06:45
import java.util.concurrent.Semaphore;
public class Test2 {
/**
* 哲学家进餐问题
*/
public static void main(String[] args) {
new Thread(new philosopher(0)).start();
new Thread(new philosopher(1)).start();
new Thread(new philosopher(2)).start();
new Thread(new philosopher(3)).start();
new Thread(new philosopher(4)).start();
}


}
class Signs2{ //信号量
final static int philosophers = 5; //哲学家的人数
final static int THINKING = 0;//思考
final static int EATING = 1;//进餐
static int[] status = new int[philosophers];//五个哲学家五种状态  默认THINKING
static Semaphore[] s = null;//记录哲学家是否可以进餐,不进餐则阻塞
static Semaphore mutex = new Semaphore(1);// 互斥信号量  

static{
s = new Semaphore[philosophers];
for(int i = 0;i<philosophers;i++){
s[i] = new Semaphore(0);//初始化
}
}
}
class philosopher implements Runnable{
private int pid;//当前哲学家id
private int lid;//左边哲学家id
private int rid;//右边哲学家id

public philosopher(int id) {//构造函数
super();
this.pid = id;
this.lid = (id+4)%5;
this.rid = (id+1)%5;
}
public void test(int pid){
// 如果当前哲学家在思考,左右两边的哲学家没有进食,则他可以进食
if(Signs2.status[pid]==Signs2.THINKING&&Signs2.status[lid]!=Signs2.EATING&&Signs2.status[rid]!=Signs2.EATING){
Signs2.status[pid]=Signs2.EATING;//可以吃  其他两个则不能进食
Signs2.s[pid].release();// 吃完释放1个许可
}

}
@Override
public void run() {
try{
while(true){
//尝试进餐
Signs2.mutex.acquire();
test(pid);
Signs2.mutex.release();


//判断当前哲学家进餐的状况,不能进餐 则 阻塞
Signs2.s[pid].acquire();
System.out.println("#"+pid+"号哲学家正在进餐。。。。。");

//放下刀叉,唤醒左右哲学家,,让他们尝试进餐
Signs2.mutex.acquire();
Signs2.status[pid] = Signs2.THINKING;//开始思考

test(lid);//让左手边的哲学家 尝试进餐, 如果可以 则释放他的许可
test(rid);//同上

Signs2.mutex.release();//释放信号量
}


}catch(Exception e){
e.printStackTrace();
}
}

}



import java.util.Random;
import java.util.concurrent.Semaphore;
/**
 * 生产者与消费者的问题
 * 
 * */
class Signs {
static Semaphore empty = new Semaphore(10); // 信号量:记录仓库空的位置
static Semaphore full = new Semaphore(0); // 信号量:记录仓库满的位置
static Semaphore mutex = new Semaphore(1); // 临界区互斥访问信号量, 相当于互斥锁。
}


//生产一个产品
class Producer implements Runnable {
Random r = new Random(1000);
public void run() {
try {
while (true) {
Signs.empty.acquire(); // 递减仓库空信号量
Signs.mutex.acquire(); // 进入临界区
Test.COUNT++;
System.out.println("生产一个产品放入仓库,剩余:"+Test.COUNT);


Signs.mutex.release(); // 离开临界区
Signs.full.release(); // 递增仓库满信号量
Thread.currentThread().sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//消费一个产品
class Consumer implements Runnable {


public void run() {
try {
while (true) {
Signs.full.acquire(); // 递减仓库满信号量
Signs.mutex.acquire();
Test.COUNT--;
System.out.println("C1拿出一个产品消费,剩余:"+Test.COUNT);


Signs.mutex.release();
Signs.empty.release(); // 递增仓库空信号量
Thread.currentThread().sleep((1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer2 implements Runnable {


public void run() {
try {
while (true) {
Signs.full.acquire(); // 递减仓库满信号量
Signs.mutex.acquire();
Test.COUNT--;
System.out.println("C2拿出一个产品消费,剩余:"+Test.COUNT);


Signs.mutex.release();
Signs.empty.release(); // 递增仓库空信号量
Thread.currentThread().sleep((500));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


public class Test {
public static int COUNT=0;//产品数目

public static void main(String[] args) {
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
new Thread(new Consumer2()).start();
}
}