> 文档中心 > 经典进程同步问题(Java实现)

经典进程同步问题(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、生产者消费者问题

  1. Good

    import lombok.ToString;@ToStringpublic class Good {    private final String goodName;    public static Integer goodId = 0;    public Good(String producerName) { this.goodName = producerName+ " 生产的第 " + goodId + "产品";    }}
  2. 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();     } }    }}
  3. 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(); }    }}
  4. 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();    }}
  5. 运行结果 (自行配合生产者、与消费者的生产、消费速度)

    生产者四 生产了 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、哲学家就餐问题

  1. 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();     } }    }}
  2. 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(); }    }}
  3. 运行结果

    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、读者、写者问题

  1. 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();     } }    }}
  2. 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();     } }    }}
  3. 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();    }}
  4. 运行结果

    写者一: 编辑 读者一: 读书 读者二: 读书 读者一: 读书 写者一: 编辑 读者二: 读书 读者一: 读书 写者一: 编辑 

经典进程同步问题(Java实现) 《新程序员》:云原生和全面数字化实践 经典进程同步问题(Java实现) 50位技术专家共同创作,文字、视频、音频交互阅读