该题系吉林大学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() {
@Override
public void actionPerformed(ActionEvent e) {
new Thread(new Read(reader)).start();
reader++;
}
});
jButton2.addActionListener(new ActionListener() {
@Override
public 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,读者互斥访问count
if(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