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();
}
}
}