哲学家每天除了思考就是吃饭,假设一张桌子上坐了5名哲学家,他们吃饭时都必须获取两根筷子,并且他们都有着相同的习惯,先拿起左边的筷子再拿起有右边的筷子,如果获取不到两根筷子就等待。
package zhexuejia;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.apache.log4j.Logger;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Log4j
public class Philosopher implements Runnable {
static Logger logger = Logger.getLogger(Philosopher.class);
private static int[] kuaizi = {1, 1, 1, 1, 1};
private int i=0;
@Override
public void run() {
synchronized (kuaizi) {
try {
eat(String.valueOf(Thread.currentThread().getName()));
} catch (Exception e) {
e.printStackTrace();
}
think(String.valueOf(Thread.currentThread().getName()));
}
}
private void eat (String string) throws Exception {
while (true) {
if (kuaizi[i]==1) {
kuaizi[i]--;
logger.info(Thread.currentThread().getName()+ "拿起左筷子");
break;
}
}
Thread.sleep(1000);
while (true) {
if (kuaizi[(i+1)%5]==1) {
kuaizi[(i+1)%5]--;
logger.info(Thread.currentThread().getName()+ "拿起右筷子");
break;
}
}
logger.info(Thread.currentThread().getName()+ "开始吃东西");
}
private void think(String name) {
//放下筷子
kuaizi[i] = 1;
kuaizi[(i+1)%5] = 1;
logger.info(Thread.currentThread().getName()+"放下了左右筷子");
logger.info(Thread.currentThread().getName()+ "开始思考");
logger.info("=====================================");
}
}
在测试方法中,按照筷子的位置(0-4)循环创建线程并执行eat和think方法,即可实现让哲学家(0-n)轮流进餐。
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import zhexuejia.Philosopher;
import org.apache.log4j.Logger;
public class PhilosopherTest {
static Logger logger = Logger.getLogger(PhilosopherTest.class);
@Test
public void test() {
while (true) {
for (int i = 4; i >= 0; i--) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Philosopher philosopher = ctx.getBean("philosopher" + i, Philosopher.class);
Thread thread = new Thread(philosopher);
thread.setName("哲学家-" +i);
thread.start();
}
}
}
}
此方法直接锁定筷子(资源),不解放其他人就无法吃饭。
[2021-01-13 17:33:51:354] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:32)]
哲学家-4拿起左筷子
[2021-01-13 17:33:52:356] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:40)]
哲学家-4拿起右筷子
[2021-01-13 17:33:52:356] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:44)]
哲学家-4开始吃东西
[2021-01-13 17:33:52:356] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:50)]
哲学家-4放下了左右筷子
[2021-01-13 17:33:52:357] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:51)]
哲学家-4开始思考
[2021-01-13 17:33:52:357] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:52)]
=====================================
[2021-01-13 17:33:52:357] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:32)]
哲学家-1拿起左筷子
[2021-01-13 17:33:53:358] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:40)]
哲学家-1拿起右筷子
[2021-01-13 17:33:53:358] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:44)]
哲学家-1开始吃东西
[2021-01-13 17:33:53:358] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:50)]
哲学家-1放下了左右筷子
[2021-01-13 17:33:53:358] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:51)]
哲学家-1开始思考
[2021-01-13 17:33:53:358] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:52)]
=====================================
[2021-01-13 17:33:53:358] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:32)]
哲学家-2拿起左筷子
[2021-01-13 17:33:54:359] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:40)]
哲学家-2拿起右筷子
[2021-01-13 17:33:54:359] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:44)]
哲学家-2开始吃东西
[2021-01-13 17:33:54:359] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:50)]
哲学家-2放下了左右筷子
[2021-01-13 17:33:54:360] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:51)]
哲学家-2开始思考
[2021-01-13 17:33:54:360] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:52)]
=====================================
[2021-01-13 17:33:54:360] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:32)]
哲学家-3拿起左筷子
[2021-01-13 17:33:55:362] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:40)]
哲学家-3拿起右筷子
[2021-01-13 17:33:55:362] [INFO ] [method:zhexuejia.Philosopher.eat(Philosopher.java:44)]
哲学家-3开始吃东西
[2021-01-13 17:33:55:362] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:50)]
哲学家-3放下了左右筷子
[2021-01-13 17:33:55:362] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:51)]
哲学家-3开始思考
[2021-01-13 17:33:55:362] [INFO ] [method:zhexuejia.Philosopher.think(Philosopher.java:52)]
=====================================
可以看到哲学家拿起左右筷子隔了1s。