java
import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; class Philosopher implements Runnable{ private final String name; private final ReentrantLock left; private final ReentrantLock right; private final AtomicInteger hunger = new AtomicInteger(3); public Philosopher(String name, ReentrantLock left, ReentrantLock right) { this.name = name; this.left = left; this.right = right; } @Override public void run() { while (this.hunger.get() > 0) { System.out.println(name + " Hungry"); this.left.lock(); this.right.lock(); System.out.println(name + " Eating"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } this.right.unlock(); this.left.unlock(); System.out.println(name + " Thinking"); this.hunger.decrementAndGet(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class DiningPhilosopher { public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); String[] philosophers = new String[] {"Mark", "Russell", "Rocky", "Haris", "Root"}; ReentrantLock fork0 = new ReentrantLock(); ReentrantLock forkLeftLock = fork0; List<Philosopher> philosopherList = new ArrayList<Philosopher>(); for(int i=1;i<philosophers.length;i++) { String name = philosophers[i]; ReentrantLock forkRightLock = new ReentrantLock(); philosopherList.add(new Philosopher(name, forkLeftLock, forkRightLock)); forkLeftLock = forkRightLock; } philosopherList.add(new Philosopher(philosophers[0], fork0, forkLeftLock)); for (Philosopher philosopher : philosopherList) { executor.submit(philosopher); } executor.shutdown(); } }
go
package main import ( "hash/fnv" "log" "math/rand" "os" "sync" "time" ) // 初始化5个人 var ph = []string{"Mark", "Russell", "Rocky", "Haris", "Root"} const hunger = 3 // 每个哲学家吃几次饭 const think = time.Second / 100 // 思考时间 const eat = time.Second / 100 // 吃饭时间 var fmt = log.New(os.Stdout, "", 0) var dining sync.WaitGroup func diningProblem(phName string, dominantHand, otherHand *sync.Mutex) { fmt.Println(phName, "Seated") h := fnv.New64a() h.Write([]byte(phName)) rg := rand.New(rand.NewSource(int64(h.Sum64()))) rSleep := func(t time.Duration) { time.Sleep(t/2 + time.Duration(rg.Int63n(int64(t)))) } for h := hunger; h > 0; h-- { fmt.Println(phName, "Hungry") dominantHand.Lock() // 获取资源 otherHand.Lock() fmt.Println(phName, "Eating") rSleep(eat) dominantHand.Unlock() // 释放资源 otherHand.Unlock() fmt.Println(phName, "Thinking") rSleep(think) } fmt.Println(phName, "Satisfied") dining.Done() fmt.Println(phName, "Left the table") } func main() { fmt.Println("Table empty") dining.Add(5) fork0 := &sync.Mutex{} forkLeft := fork0 for i := 1; i < len(ph); i++ { forkRight := &sync.Mutex{} go diningProblem(ph[i], forkLeft, forkRight) forkLeft = forkRight } go diningProblem(ph[0], fork0, forkLeft) dining.Wait() // 等待结束 fmt.Println("Table empty") }