写优先的读者写者问题(Java实现)

article/2025/9/30 9:53:59

该题系吉林大学19级软件学院操作系统课设题之一

 

 

先输入初始时的写者读者情况,优先级顺序做了随机处理

 

代码如下

GUI:


import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;public class ReadAndWrite extends JFrame {public static Semaphore rw = new Semaphore(1);public static Semaphore mutex = new Semaphore(1);public static Semaphore w = new Semaphore(1);public static Semaphore fresh = new Semaphore(1);public static int count = 0;public static LinkedList<String> Re = new LinkedList<String>();//读空间public static LinkedList<String> Wr = new LinkedList<String>();//写空间public static LinkedList<String> ing = new LinkedList<String>();//正在的状态private int reader = 0;//写者数量和编号记录private int writer = 0;//读者数量和编号记录//三个大的文本区域static JTextPane jTextPane1 = new JTextPane();//读static JTextPane jTextPane2 = new JTextPane();//文件static JTextPane jTextPane3 = new JTextPane();//写ReadAndWrite(int a, int b){super("写优先的读者写者问题");reader = a+1;writer = b+1;for(int i = 1;i<=a;i++)new Thread(new Read(i)).start();for(int i = 1;i<=b;i++)new Thread(new Write(i)).start();setBounds(400,300,600,500);JPanel jPanel1 = new JPanel(new BorderLayout());//读JPanel jPanel2 = new JPanel(new BorderLayout());//临界区JPanel jPanel3 = new JPanel(new BorderLayout());//写jPanel1.setBackground(Color.CYAN);jPanel2.setBackground(Color.PINK);jPanel3.setBackground(Color.CYAN);this.add(jPanel1,BorderLayout.WEST);this.add(jPanel2,BorderLayout.CENTER);this.add(jPanel3,BorderLayout.EAST);JLabel label1 = new JLabel("       读者       ");JLabel label2 = new JLabel("        临界区");JLabel label3 = new JLabel("       写者       ");label1.setFont(new Font("宋体",Font.BOLD,20));label2.setFont(new Font("宋体",Font.BOLD,20));label3.setFont(new Font("宋体",Font.BOLD,20));jPanel1.add(label1,BorderLayout.NORTH);jPanel2.add(label2,BorderLayout.NORTH);jPanel3.add(label3,BorderLayout.NORTH);jTextPane2.setLayout(new FlowLayout(FlowLayout.CENTER));//没起作用jTextPane1.setEditable(false);//禁止编辑jTextPane2.setEditable(false);jTextPane3.setEditable(false);//三个大的文本区域jTextPane1.setFont(new Font("宋体",Font.BOLD,16));jTextPane2.setFont(new Font("宋体",Font.BOLD,16));jTextPane3.setFont(new Font("宋体",Font.BOLD,16));jPanel1.add(new JScrollPane(jTextPane1),BorderLayout.CENTER);jPanel2.add(new JScrollPane(jTextPane2),BorderLayout.CENTER);jPanel3.add(new JScrollPane(jTextPane3),BorderLayout.CENTER);JButton jButton1 = new JButton("加入读者");JButton jButton2 = new JButton("加入写者");jButton1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {new Thread(new Read(reader)).start();reader++;}});jButton2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {new Thread(new Write(writer)).start();writer++;}});jPanel1.add(jButton1,BorderLayout.SOUTH);jPanel3.add(jButton2,BorderLayout.SOUTH);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);}public static void insert1(String str)//读模块的gui部分{SimpleAttributeSet set = new SimpleAttributeSet();StyleConstants.setUnderline(set, true);try{jTextPane1.getDocument().insertString(jTextPane1.getDocument().getLength(), str + "\n", set);}catch (BadLocationException e){e.printStackTrace();}}public static void insert2(String str)//被访问文件模块的gui部分{SimpleAttributeSet set = new SimpleAttributeSet();StyleConstants.setUnderline(set, true);try{jTextPane2.getDocument().insertString(jTextPane2.getDocument().getLength(), str + "\n", set);}catch (BadLocationException e){e.printStackTrace();}}public static void insert3(String str)//写模块的gui部分{SimpleAttributeSet set = new SimpleAttributeSet();StyleConstants.setUnderline(set, true);try{jTextPane3.getDocument().insertString(jTextPane3.getDocument().getLength(), str + "\n", set);}catch (BadLocationException e){e.printStackTrace();}}public static void refresh(){jTextPane1.setText(null);jTextPane2.setText(null);jTextPane3.setText(null);for(String a : Re){insert1("读者"+a);}for(String b : ing){insert2(b);}for(String c : Wr){insert3("写者"+c);}}public static void main(String[] args){int a = Integer.parseInt(JOptionPane.showInputDialog("请输入初始读者数量"));int b = Integer.parseInt(JOptionPane.showInputDialog("请输入初始写者数量"));new ReadAndWrite(a,b);
//        new Thread(new Read(1)).start();
//        new Thread(new Read(2)).start();
//        new Thread(new Read(3)).start();
//        new Thread(new Write(1)).start();
//        new Thread(new Write(2)).start();}
}

写者

import java.util.concurrent.Semaphore;import java.util.Random;public class Read extends Thread{private int num;Read(int num){this.num = num;}public void run() {try {synchronized(this){Random random = new Random();wait(random.nextInt(500));ReadAndWrite.insert1("读者"+num+"打算读文件");ReadAndWrite.Re.add(num+"打算读文件");ReadAndWrite.w.acquire();           //实现写有先ReadAndWrite.mutex.acquire();       //防止读者之间同步访问count,读者互斥访问countif(ReadAndWrite.count==0)ReadAndWrite.rw.acquire();      //实现读写互斥ReadAndWrite.count++;               //我只要有东西正在读你,你就不许给我写东西,实现多读者同步的关键ReadAndWrite.mutex.release();ReadAndWrite.w.release();//以下为读文件的阶段ReadAndWrite.insert2("读者"+num+"正在读文件");ReadAndWrite.ing.add("读者"+num+"正在读文件");wait(random.nextInt(5000)+1500);ReadAndWrite.insert2("读者"+num+"结束读文件");ReadAndWrite.insert1("读者"+num+"完成读文件");ReadAndWrite.ing.remove("读者"+num+"正在读文件");ReadAndWrite.Re.remove(num+"打算读文件");//以上为读文件的阶段wait(3000);ReadAndWrite.fresh.acquire();              //实现刷新页面时,线程的互斥ReadAndWrite.refresh();                    //刷新页面,通过队列的信息刷新页面ReadAndWrite.fresh.release();ReadAndWrite.mutex.acquire();ReadAndWrite.count--;                   //文件读完了,读完一个出来一个,count--了if(ReadAndWrite.count==0)ReadAndWrite.rw.release();ReadAndWrite.mutex.release();}} catch (InterruptedException e) {System.out.println("读者"+num+"出现错误!");e.printStackTrace();}}}

读者

import java.util.Random;public class Write extends Thread
{private int num;Write(int num){this.num = num;}public void run(){try{synchronized(this){Random random = new Random();wait(random.nextInt(500));ReadAndWrite.insert3("写者"+num+"打算写文件");ReadAndWrite.Wr.add(num+"打算写文件");ReadAndWrite.w.acquire();ReadAndWrite.rw.acquire();ReadAndWrite.insert2("写者"+num+"正在写文件");ReadAndWrite.ing.add("写者"+num+"正在写文件");wait(random.nextInt(10000)+3000);ReadAndWrite.insert2("写者"+num+"结束写文件");ReadAndWrite.insert3("写者"+num+"完成写文件");ReadAndWrite.ing.remove("写者"+num+"正在写文件");ReadAndWrite.Wr.remove(num+"打算写文件");wait(3000);ReadAndWrite.fresh.acquire();ReadAndWrite.refresh();//刷新页面,通过队列的信息刷新页面ReadAndWrite.fresh.release();ReadAndWrite.rw.release();ReadAndWrite.w.release();}} catch (InterruptedException e){System.out.println("写者"+num+"出现错误!");e.printStackTrace();}}
}

环境:IDEA

 


http://chatgpt.dhexx.cn/article/U9jwDccO.shtml

相关文章

操作系统读者写者问题代码实现

问题分析&#xff1a; 读者优先: 读者进程执行: 无其他读者写者, 直接执行有写者等, 但其他读者在读, 直接读有写者写, 等待写者进程执行: 无其他读写者, 直接执行有其他读写者, 等待 写者优先: 读者进程执行: 如果此时没有写者等待, 直接执行如果有写者等待, 那么等待写者…

读者写者问题详解 操作系统

2.16 读者写者问题 抽象解释 多个进程访问一个共享的数据区读者&#xff08;读进程&#xff09;只能读数据&#xff0c;写者&#xff08;写进程&#xff09;只能写数据适用于数据库、文件、内存、寄存器等数据区的访问模型如12306购票系统&#xff0c;由于用户量庞大和数据量…

同步机制—读者写者问题

【实验目的】 理解临界区和进程互斥的概念&#xff0c;掌握用信号量和PV操作实现进程互斥的方法。 【实验内容】 在windows或者linux环境下编写一个控制台应用程序&#xff0c;该程序运行时能创建N个线程&#xff0c;其中既有读者线程又有写者线程&#xff0c;它们按照事先设计…

操作系统——读者写者问题

一、问题描述 要求: 1、允许多个读者可以同时对文件执行读操作。 2、只允许一个写者往文件中写信息。 3、任一写者在完成写操作之前不允许其他读者或写者工作。 4、写者执行写操作前,应让已有的读者和写者全部退出。 二、问题分析 读者写者问题最核心的问题是如何处理…

【操作系统-进程】PV操作——读者写者问题

文章目录 读者写者问题万能模板万能模板 1——读进程优先万能模板 2——读写公平法万能模板 3——写进程优先 题目 1&#xff1a;南北过桥问题题目 2&#xff1a;录像厅问题题目 3&#xff1a;更衣问题 读者写者问题万能模板 读者写者问题&#xff0c;其本质就是连续多个同类进…

经典进程同步问题(三)——读者写者问题

目录 一、问题描述 二、解题思路 2.1 读者优先算法 2.2 写者优先算法 2.3 读写公平 三、源码实现 3.1 读者优先 3.2 写者优先 3.3 读写平等 一、问题描述 一个数据问价或记录可以被多个进程共享&#xff0c;我们把只读该文件的进程称为“读者进程”&#xff0c;其他进…

2. 堆与栈的区别

2. 堆与栈的区别 在理解这两个概念时&#xff0c;需要放到具体的场景下&#xff0c;因为不同场景下&#xff0c;堆与栈代表不同的含义。一般情况下&#xff0c;有两层含义&#xff1a; &#xff08;1&#xff09;程序内存布局场景下&#xff0c;堆与栈表示的是两种内存管理方式…

栈与堆的区别(内存分配与数据结构)

参考自https://blog.csdn.net/K346K346/article/details/80849966/ 堆&#xff08;Heap&#xff09;与栈&#xff08;Stack&#xff09;包含两层含义&#xff1a; 程序内存布局场景下的内存管理方式数据结构中的两种常见的数据结构 1. 程序内存分配中的堆与栈 1.1 栈介绍 …

C语言里栈和堆的区别整理

这里说的是C语言程序内存分配中的堆和栈。下面先谈谈C语言的内存管理&#xff1a; 可执行程序在存储时&#xff08;没有调到内存&#xff09;分为代码区&#xff08;text&#xff09;、数据区&#xff08;data&#xff09;和未初始化数据区&#xff08;bss&#xff09;3个部分。…

看懂堆与栈的区别与联系

<div class"simditor-body clearfix" style"height: auto; overflow: inherit;"><h2> <strong>  堆和栈概要</strong></h2>在计算机领域&#xff0c;堆栈是一个不容忽视的概念&#xff0c;堆栈是两种数据结构。堆栈都是一…

C语言:栈和堆的区别

c语言五大内存分区 栈区&#xff08;stack&#xff09;:存放函数形参和局部变量&#xff08;auto类型&#xff09;&#xff0c;由编译器自动分配和释放 堆区&#xff08;heap&#xff09;:该区由程序员申请后使用&#xff0c;需要手动释放否则会造成内存泄漏。如果程序员没有手…

什么是栈(Stack)?什么是堆(Heap)?栈和堆的区别是什么?

原参考地址&#xff1a;https://zhidao.baidu.com/question/36918441.html 栈&#xff1a;由操作系统自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量du的值等。其操作方式类似于数据结构中的栈&#xff1b; 堆&#xff1a; 一般由程序员分配释放&#xff0c…

堆和栈的概念和区别

在说堆和栈之前&#xff0c;我们先说一下JVM&#xff08;虚拟机&#xff09;内存的划分&#xff1a; Java程序在运行时都要开辟空间&#xff0c;任何软件在运行时都要在内存中开辟空间&#xff0c;Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域&#x…

堆与栈的区别详细总结

1、堆与栈的区别详细总结_Fighting的博客-CSDN博客_堆和栈的区别 2、堆和栈的区别 - 江雨牧 - 博客园 3、堆和栈的区别_内外皆秀的博客-CSDN博客_堆和栈的区别 4、一文读懂堆与栈的区别_恋喵大鲤鱼的博客-CSDN博客_堆和栈的区别 一般情况下&#xff0c;如果有人把堆栈合起来…

栈和堆的区别

栈和堆的区别 前面已经介绍过&#xff0c;栈是由编译器在需要时分配的&#xff0c;不需要时自动清除的变量存储区。里面的变量通常是局部变量、函数参数等。堆是由malloc()函数分配的内存块&#xff0c;内存释放由程序员手动控制&#xff0c;在C语言为free函数完成。栈和堆的主…

Struts常见面试题

Struts分为Struts1和Struts2&#xff0c;默认情况下指的是Struts2&#xff0c;Struts1除非特别说明。 1、Struts2 中的 # 和 % 分别是做什么的&#xff1f; &#xff08;1&#xff09;使用#获取 context 里面的数据 <s:iterator value “list” var”user”> <s:p…

关于Struts2的笔试题(一)

一. struts2框架中struts.xml配置文件,package标签的属性有那几个?各有什么功能? 1.name属性 作用:定义一个包的名称&#xff0c;它必须唯一。 2.namespace属性 作用:主要是与action标签的name属性联合使用来确定一个action 的访问路径 3.extends属性 作用:指定继承自哪个…

Struts2详述一(struts2基础及2个核心)

临近大学毕业了&#xff0c;在毕业之前做点大学学到的知识和总结。如有哪些方面存在错误还望大神见谅。 首先&#xff0c;这里想从SSH这三大框架说起。首选从最简单的Struts2说起。这一篇我将讲述struts2一些基础及2个核心&#xff08;Action和result&#xff09;,下篇我们将着…

【面试】【Struts2常见问题总结】【02】

【常见面试问题总结目录>>>】 031 struts2如何对指定的方法进行验证&#xff1f; 1.validate()方法会校验action中所有与execute方法签名相同的方法&#xff1b;   2.要校验指定的方法通过重写validateXxx()方法实现&#xff0c; validateXxx()只会校验action中方法…

【面试】【Struts2常见问题总结】【01】

【常见面试问题总结目录>>>】 001 请简述struts1的工作流程和机制&#xff1a; Struts的工作流程:   在web应用启动时就会加载初始化ActionServlet,ActionServlet从   struts-config.xml文件中读取配置信息,把它们存放到各种配置对象   当ActionServlet接收到…