经典进程同步问题(Java实现)
经典进程同步问题(Java实现)
maven 依赖:(使用 lombok 简化开发)
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version></dependency>
1、实现 PV 操作
package Common;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@NoArgsConstructor@AllArgsConstructorpublic class Semaphore { private int count; public synchronized void P(){ count--; if (count >= 0) { return; } else { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void V(){ count++; if (count > 0) { return; } else { this.notify(); } }}
2、生产者、消费者问题
-
Good
import lombok.ToString;@ToStringpublic class Good { private final String goodName; public static Integer goodId = 0; public Good(String producerName) { this.goodName = producerName+ " 生产的第 " + goodId + "产品"; }}
-
Producer
public class Producer extends Thread{ private Good good; public Producer(String name) { super(name); } private void produceGood() throws InterruptedException { sleep((int) (Math.random() * Buffer.PRODUCER_SPEED)); Buffer.mutex_good_id.P(); if (Good.goodId < Buffer.PRODUCE_GOOD_NUM) { Good.goodId++; } else { this.stop(); } Buffer.mutex_good_id.V(); good = new Good(getName()); } public void putGood() throws InterruptedException { produceGood(); Buffer.empty.P(); Buffer.mutex.P(); for (int i = 0; i < Buffer.BUFFER_SIZE; i++) { if (Buffer.buffer[i] == null) { Buffer.buffer[i] = good; System.out.println(getName() + " 生产了 " + Buffer.buffer[i]); break; } } Buffer.mutex.V(); Buffer.full.V(); } @Override public void run() { while (true) { try { putGood(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
-
Consumer
public class Consumer extends Thread{ private Integer consumeGoodNum = 0; public Consumer (String name) { super(name); } private void consumeGood() throws InterruptedException { sleep((int) (Math.random() * Buffer.CONSUMER_SPEED)); } public void getGood() throws InterruptedException { Buffer.full.P(); Buffer.mutex.P(); for (int i = 0; i < Buffer.BUFFER_SIZE; i++) { if (Buffer.buffer[i] != null) { System.out.println("\t\t\t\t\t\t\t\t\t\t\t\t\t\t" + getName() + " 消费了 " + Buffer.buffer[i]); Buffer.buffer[i] = null; break; } } Buffer.mutex.V(); Buffer.empty.V(); consumeGood(); } @Override public void run() { while (true){ try { getGood(); } catch (InterruptedException e) { e.printStackTrace(); } Buffer.mutex_consume_num.P(); if (consumeGoodNum >= Buffer.PRODUCE_GOOD_NUM){ this.stop(); } consumeGoodNum ++; Buffer.mutex_consume_num.V(); } }}
-
Buffer
import Common.Semaphore;public class Buffer { public static final int BUFFER_SIZE = 15; public static final int PRODUCE_GOOD_NUM = 30; public static Good[] buffer = new Good[BUFFER_SIZE]; public static final int PRODUCER_SPEED = 2000; public static final int CONSUMER_SPEED = 2000; public static Semaphore mutex = new Semaphore(1); public static Semaphore mutex_good_id = new Semaphore(1); public static Semaphore mutex_consume_num = new Semaphore(1); public static Semaphore empty = new Semaphore(BUFFER_SIZE); public static Semaphore full = new Semaphore(0); public static void main(String[] args) { Thread producer1 = new Producer("生产者一"); Thread producer2 = new Producer("生产者二"); Thread producer3 = new Producer("生产者三"); Thread producer4 = new Producer("生产者四"); Thread comsumer1 = new Consumer("消费者一"); Thread comsumer2 = new Consumer("消费者二"); producer1.start(); producer2.start(); producer3.start(); producer4.start(); comsumer1.start(); comsumer2.start(); }}
-
运行结果 (自行配合生产者、与消费者的生产、消费速度)
生产者四 生产了 Good(goodName=生产者四 生产的第 1产品)消费者一 消费了 Good(goodName=生产者四 生产的第 1产品)生产者二 生产了 Good(goodName=生产者二 生产的第 2产品)消费者二 消费了 Good(goodName=生产者二 生产的第 2产品)生产者四 生产了 Good(goodName=生产者四 生产的第 3产品)生产者一 生产了 Good(goodName=生产者一 生产的第 4产品)生产者三 生产了 Good(goodName=生产者三 生产的第 5产品)生产者一 生产了 Good(goodName=生产者一 生产的第 6产品)消费者二 消费了 Good(goodName=生产者四 生产的第 3产品)消费者一 消费了 Good(goodName=生产者一 生产的第 4产品)生产者四 生产了 Good(goodName=生产者四 生产的第 7产品)生产者三 生产了 Good(goodName=生产者三 生产的第 8产品)消费者二 消费了 Good(goodName=生产者四 生产的第 7产品)消费者二 消费了 Good(goodName=生产者三 生产的第 8产品)生产者四 生产了 Good(goodName=生产者四 生产的第 9产品)生产者二 生产了 Good(goodName=生产者二 生产的第 10产品)消费者一 消费了 Good(goodName=生产者四 生产的第 9产品)生产者三 生产了 Good(goodName=生产者三 生产的第 11产品)生产者一 生产了 Good(goodName=生产者一 生产的第 12产品)消费者二 消费了 Good(goodName=生产者三 生产的第 11产品)消费者二 消费了 Good(goodName=生产者二 生产的第 10产品)消费者一 消费了 Good(goodName=生产者三 生产的第 5产品)生产者一 生产了 Good(goodName=生产者一 生产的第 13产品)生产者一 生产了 Good(goodName=生产者一 生产的第 14产品)生产者四 生产了 Good(goodName=生产者四 生产的第 15产品)生产者四 生产了 Good(goodName=生产者四 生产的第 16产品)生产者二 生产了 Good(goodName=生产者二 生产的第 17产品)生产者三 生产了 Good(goodName=生产者三 生产的第 18产品)生产者一 生产了 Good(goodName=生产者一 生产的第 19产品)生产者三 生产了 Good(goodName=生产者三 生产的第 20产品)消费者二 消费了 Good(goodName=生产者一 生产的第 13产品)生产者二 生产了 Good(goodName=生产者二 生产的第 21产品)消费者一 消费了 Good(goodName=生产者二 生产的第 21产品)生产者三 生产了 Good(goodName=生产者三 生产的第 22产品)消费者二 消费了 Good(goodName=生产者三 生产的第 22产品)生产者四 生产了 Good(goodName=生产者四 生产的第 23产品)生产者三 生产了 Good(goodName=生产者三 生产的第 24产品)消费者二 消费了 Good(goodName=生产者四 生产的第 23产品)生产者三 生产了 Good(goodName=生产者三 生产的第 25产品)生产者一 生产了 Good(goodName=生产者一 生产的第 26产品)生产者四 生产了 Good(goodName=生产者四 生产的第 27产品)生产者二 生产了 Good(goodName=生产者二 生产的第 28产品)消费者一 消费了 Good(goodName=生产者三 生产的第 25产品)生产者三 生产了 Good(goodName=生产者三 生产的第 29产品)生产者四 生产了 Good(goodName=生产者四 生产的第 30产品)消费者二 消费了 Good(goodName=生产者三 生产的第 29产品)消费者一 消费了 Good(goodName=生产者一 生产的第 14产品)消费者一 消费了 Good(goodName=生产者四 生产的第 15产品)消费者一 消费了 Good(goodName=生产者一 生产的第 6产品)消费者二 消费了 Good(goodName=生产者一 生产的第 12产品)消费者二 消费了 Good(goodName=生产者四 生产的第 16产品)消费者二 消费了 Good(goodName=生产者二 生产的第 17产品)消费者一 消费了 Good(goodName=生产者三 生产的第 18产品)消费者一 消费了 Good(goodName=生产者一 生产的第 19产品)消费者一 消费了 Good(goodName=生产者三 生产的第 20产品)消费者二 消费了 Good(goodName=生产者三 生产的第 24产品)消费者二 消费了 Good(goodName=生产者一 生产的第 26产品)消费者一 消费了 Good(goodName=生产者四 生产的第 27产品)消费者一 消费了 Good(goodName=生产者二 生产的第 28产品)消费者二 消费了 Good(goodName=生产者四 生产的第 30产品)
3、哲学家就餐问题
-
Philosopher
import lombok.Data;@Datapublic class Philosopher extends Thread { private int philosopherId; public Philosopher(String name) { super(name); } public Philosopher(int philosopherId) { this.philosopherId = philosopherId; } public void think(){ try { sleep((int) (Math.random() * Table.PHILOSOPHER_THINK_TIME)); } catch (InterruptedException e) { e.printStackTrace(); } } public void eat() throws InterruptedException { Table.chopstick[philosopherId].P(); Table.chopstick[(philosopherId+1)%Table.PHILOSOPHER_NUM].P(); System.out.println( philosopherId + " 号哲学家拿起 " + philosopherId + " 和 " + (philosopherId+1) + " 号筷子 开始就餐"); sleep((int) (Math.random() * Table.PHILOSOPHER_EAT_TIME)); Table.chopstick[philosopherId].V(); Table.chopstick[(philosopherId+1)%Table.PHILOSOPHER_NUM].V(); } @Override public void run() { while (true) { think(); try { eat(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
-
Table
import Common.Semaphore;public class Table { public static final int PHILOSOPHER_NUM = 5; public static final int PHILOSOPHER_THINK_TIME = 10000; public static final int PHILOSOPHER_EAT_TIME = 5000; public static Semaphore[] chopstick = new Semaphore[PHILOSOPHER_NUM]; public static void main(String[] args) { for (int i = 0; i < PHILOSOPHER_NUM; i++) { chopstick[i] = new Semaphore(1); } Philosopher philosophers[] = new Philosopher[PHILOSOPHER_NUM]; for (int i = 0; i < PHILOSOPHER_NUM; i++) { philosophers[i] = new Philosopher(i); philosophers[i].start(); } }}
-
运行结果
2 号哲学家拿起 2 和 3 号筷子 开始就餐4 号哲学家拿起 4 和 5 号筷子 开始就餐0 号哲学家拿起 0 和 1 号筷子 开始就餐4 号哲学家拿起 4 和 5 号筷子 开始就餐1 号哲学家拿起 1 和 2 号筷子 开始就餐3 号哲学家拿起 3 和 4 号筷子 开始就餐0 号哲学家拿起 0 和 1 号筷子 开始就餐2 号哲学家拿起 2 和 3 号筷子 开始就餐.....
4、读者、写者问题
-
Reader
public class Writer extends Thread { public Writer (String name) { super(name); } public void write() throws InterruptedException { Main.wmutex.P(); System.out.println(getName() + ": 编辑 "); sleep((int) (Math.random() * Main.WRITE_TIME)); Main.wmutex.V(); } @Override public void run() { while (true) { try { write(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
-
Writer
public class Writer extends Thread { public Writer (String name) { super(name); } public void write() throws InterruptedException { Main.wmutex.P(); System.out.println(getName() + ": 编辑 "); sleep((int) (Math.random() * Main.WRITE_TIME)); Main.wmutex.V(); } @Override public void run() { while (true) { try { write(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
-
Main
import Common.Semaphore;public class Main { public static Semaphore rmutex = new Semaphore(1); public static Semaphore wmutex = new Semaphore(1); public static final int READ_TIME = 5000; public static final int WRITE_TIME = 5000; public static int readCount = 0; public static void main(String[] args) { Thread reader1 = new Reader("读者一"); Thread reader2 = new Reader("读者二"); Thread writer1 = new Writer("写者一"); reader1.start(); reader2.start(); writer1.start(); }}
-
运行结果
写者一: 编辑 读者一: 读书 读者二: 读书 读者一: 读书 写者一: 编辑 读者二: 读书 读者一: 读书 写者一: 编辑
《新程序员》:云原生和全面数字化实践
50位技术专家共同创作,文字、视频、音频交互阅读