用Java写真题(计算机操作系统考研真题)

题目背景

假设系统中有三个进程 P1、P2、P3 和一个共享缓冲区 B,缓冲区容量为 N。进程 P1 不断生成正整数并放入缓冲区;若生成的数为奇数,则由 P2 从缓冲区取出并打印;若为偶数,则由 P3 取出并打印。要求设计同步算法,确保进程正确协作且不发生死锁。


Java实现思路

1. 问题分析
  • 同步需求

    • 互斥访问:缓冲区 B 是临界资源,同一时间只能有一个进程访问。

    • 生产者-消费者关系:P1 为生产者,P2/P3 为消费者,需通过信号量控制缓冲区空位和数据的奇偶性。

  • 信号量设计

    • mutex:互斥信号量(初始值为1),保护缓冲区访问。

    • empty:缓冲区空位数量(初始值为N)。

    • odd:奇数数据可消费数量(初始值为0)。

    • even:偶数数据可消费数量(初始值为0)。

2. Java代码实现
import java.util.concurrent.Semaphore;

public class ProcessSynchronization {
    static final int N = 10; // 缓冲区容量
    static int[] buffer = new int[N]; // 共享缓冲区
    static int in = 0, out = 0; // 缓冲区指针

    // 定义信号量
    static Semaphore mutex = new Semaphore(1); // 互斥访问缓冲区
    static Semaphore empty = new Semaphore(N); // 空位数量
    static Semaphore odd = new Semaphore(0);  // 奇数数据可消费数量
    static Semaphore even = new Semaphore(0); // 偶数数据可消费数量

    // 进程P1:生产者
    static class P1 extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 1; i <= 20; i++) { // 模拟生成20个数
                    empty.acquire();  // 等待空位
                    mutex.acquire();  // 互斥访问缓冲区
                    buffer[in] = i;
                    System.out.println("P1生成: " + i);
                    in = (in + 1) % N;
                    mutex.release();  // 释放缓冲区
                    
                    if (i % 2 == 1) odd.release(); // 奇数通知P2
                    else even.release();          // 偶数通知P3
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 进程P2:奇数消费者
    static class P2 extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    odd.acquire();    // 等待奇数数据
                    mutex.acquire();
                    int num = buffer[out];
                    System.out.println("P2取出奇数: " + num);
                    out = (out + 1) % N;
                    mutex.release();
                    empty.release();  // 释放空位
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 进程P3:偶数消费者
    static class P3 extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    even.acquire();   // 等待偶数数据
                    mutex.acquire();
                    int num = buffer[out];
                    System.out.println("P3取出偶数: " + num);
                    out = (out + 1) % N;
                    mutex.release();
                    empty.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new P1().start();
        new P2().start();
        new P3().start();
    }
}

关键逻辑解析

  1. 信号量控制

    • empty:确保缓冲区不满时 P1 才能写入。

    • odd/even:根据数据奇偶性唤醒对应的消费者(P2 或 P3)。

    • mutex:保证缓冲区的原子操作,避免数据竞争。

  2. 环形缓冲区管理

    • in 和 out 指针循环移动,模拟有限缓冲区的环形结构。

  3. 线程安全与死锁避免

    • 按顺序获取信号量(先 empty 后 mutex),避免因顺序错误导致的死锁。

    • 消费者通过 odd 和 even 信号量区分任务,实现精准唤醒。


扩展思考

  • 性能优化:可引入多生产者或多消费者模型,进一步模拟复杂场景。

  • 异常处理:增加超时机制或中断响应,处理线程阻塞问题。

  • 动态调整:根据系统负载动态调整缓冲区大小(如使用 BlockingQueue 替代数组)。


真题考点关联

  • 进程同步机制:通过信号量实现互斥与条件同步,是操作系统调度算法的核心。

  • 临界区管理:展示如何通过代码实现互斥访问,呼应“并发与共享是操作系统基本特征”的理论。

  • 生产者-消费者模型:经典同步问题的变种,考察对资源分配与调度的理解。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值