经典进程同步问题(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
@AllArgsConstructor
public 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;
    
    @ToString
    public 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;
    
    @Data
    public 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. 运行结果

    写者一: 编辑 
    读者一: 读书 
    读者二: 读书 
    读者一: 读书 
    写者一: 编辑 
    读者二: 读书 
    读者一: 读书 
    写者一: 编辑 
    
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bit-apk-code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值