多进程同步橘子苹果问题完整报告(附源代码)
一、 课程设计目的
本次实验进行操作系统课程设计的主要任务是模拟生产者和消费者的一个衍生,即
实现“橘子-苹果问题”。这个问题中有两个生产者,分别生产苹果核橘子,有两个消费者,分别消费橘子和苹果。同时,因为两个生产者和两个消费者对同一个缓冲区进行操作,所以应互斥的访问缓冲区以保证程序的正确性。本次实验的目的就是加深各个进程正确有效的对资源的访问,即同步和互斥。同时掌握信号量在互斥访问中的使用。掌握生产者和消费者问题的流程和实现方法。同时提高编程的能力、对问题的解决能力及查阅文档的能力。
二、 课程设计内容与要求
1、通过研究Linux的进程同步机制和信号量,实现特殊的生产者与消费者问题的并发控制。
2、说明:有两类生产者,一类负责生产桔子,一类负责生产苹果;有两类消费者,一类负责消费桔子,一类负责消费苹果;他们共享一个有20个存储单元的有界缓冲区,每个存储单元只能放入一种产品(桔子/苹果)。 3、设计要求:
1) 二类生产者与二类消费者数目均为20,即20个生产者负责生产桔子,20个生产者
负责生产苹果;20个消费者负责消费桔子,20个消费者负责消费苹果
2) 二类生产者的生产速度与二类消费者的消费速度均可独立在程序界面调节,在运行
中,该值调整后立即生效
3) 多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码,同时需要
考虑算法的效率性
4) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、
当前生产者与消费者的指针位置,以及生产者和消费者线程标识符
5) 采用可视化界面,可在运行过程中随时暂停,查看当前生产者、消费者以及有界缓
冲区的状态
三、 系统分析与设计
1、系统分析
1.此次任务是实现特殊生产者和消费者的演示程序,所需要处理的信息是生产者和消费者的个数,生产苹果、橘子和消费苹果、橘子的速度控制,缓冲区中橘子和苹果的个数和当前生产、消费指针的位置。
2.程序中需要处理缓冲区的动态显示、生产者和消费者的速度可以调节,生产者和消费者个数可以改变。为了实现界面的友好性,应该对用户标明清楚各个模块的作用。同时实时的对程序进行暂停和停止。演示程序中用图形显示的方法描述缓冲区的使用情况,即当前缓冲区有多少个苹果和橘子,还有生产和消费者的指针。
3.系统对外的界面如下:
可以调节橘子和苹果的生产速度和消费苹果和橘子的速度,在文本框中输入相应的速度,再按下修改按键即可实现速度的实时调节。
在苹果生产者、橘子生产者、苹果消费者、橘子消费者中实现对个数按钮的按下即可动态实时的调节生产者和消费者的个数的调节。
在界面的最下面点击开始按钮,程序开始运行,暂停按钮使程序暂停挂起,再点击则可以继续运行。停止按钮实现此次程序的演示结束。
4.此次使用java平台实现,保证了程序在各种机器的运行,只需要事前建立java的运行环境即可,便于程序的移植
5.系统界面如下:
2、系统设计: 2.1、模块设计:
2.2、数据结构说明:
1.缓冲区的数据结构:双端队列
说明:左端放置生产苹果的指针,右端放置生产橘子的指针。
2.缓冲区操作的类图,实现对缓冲区的实际操作
2.3、算法流程图:
1.生产苹果算法
2.消费苹果算法
3.绘图算法
4.生产苹果者人工智能算法(生产橘子人工智能相似)
5.苹果消费者人工智能算法(生产橘子算法类似)
四、系统测试与调试分析
1、系统测试
(1)因为当苹果生产者在缓冲区满了以后自动阻塞,需要苹果消费者唤醒,所以需要测试
(2)因为当苹果生产者在缓冲区满了以后自动阻塞,需要苹果消费者唤醒,所以需要测试
(3)测试生产者和消费者的速度是否可以调节
(4)实现了人工智能操作:即系统自动保持生产者和消费者的相对平衡,测试功能的正确实现
2、调试分析:
(1)程序编写过程中,因为有两个生产者和消费者,极易把操作写错。在编写增加苹果数量额函数中,程序中午无法增加苹果数量。
解决办法:在函数中查找错误,对苹果的操作写成了对橘子的操作,导致程序出现问题。 (2)在对缓冲区进行绘图的时候,java的JComponent组件内绘图位置出现错误。 解决办法:JComponent内绘图时因为JComponent内使用的是相对坐标,所以不能使用面板的绝对坐标,换成相对坐标正确绘图。
(3)实现人工智能操作的时候,点击相应按钮无法执行
解决办法:在排查完毕后,发现按键响应没有对程序已经设计的标志值进行修改,致使程序没有按预期执行,修改完标志值即可以。
五、用户手册
1.使用的语言和平台
本次实验使用的是java 语言的eclipse平台 2.对于程序运行环境的注意事项
需要安装java运行环境,eclipss平台不需要安装,只需要下载完成就可以使用。 3.程序使用步骤
图1:系统登录界面。
图2:生产者速度调节 图3:消费者速度调节
图4:生产者数量调节 图5:消费者数量调节
图 6::控制界面
图7:动态可视化缓冲区
4.程序使用步骤:
1)单击开始按钮,程序开始初始化执行
2)点击增加按钮分别增加生产者和消费者,可以看到可视化缓冲区开始运动
3)在速度调节部分调节生产者和消费者的速度,可以看到缓冲区出现预期的产品种类和数量的变化。
4)在程序运行状态,可以点击“人工智能”按钮,可以实现人工智能自动操作缓冲区,保持缓冲区的产品数量和种类的稳定,不至于产品数量过多或过少,也不会出现某种产品数量过多或者过少。
六、程序清单
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.*;
import java.net.MalformedURLException;
import java.util.ArrayList;
import javax.print.attribute.AttributeSet;
import javax.swing.*;
import org.w3c.dom.css.Rect;
public class Apple
{
/**
* 生成一个缓冲池类对应的对象叫myStorage,以后所有的生产者线程 和消费者线程都对这个myStorage对象进行操作!
*/
static MyStorage myStorage = new MyStorage();
private JFrame window ;
// 该数组用来存取生产橘子和苹果的线程,分别20个
static Increaseapple[] appleincrease = new Increaseapple[20];
static Increaseorange[] orangeincrease = new Increaseorange[20];
// 该数组用来存放消费者线程,最多20个
static Decreaseapple[] appledecrease = new Decreaseapple[20];
static Decreaseorange[] orangedecrease = new Decreaseorange[20];
// 代表两个生产者对应线程的数目,i1为苹果,i2为橘子
static int i1 = 0;
static int i2 = 0;
// 代表消费者对应线程的数目,d1为苹果,d2为橘子
static int d1 = 0;
static int d2 = 0;
static TextArea textArea2; static JProgressBar progressbar = new JProgressBar(0,20); static Draw draw1; static JTextField t1; static JTextField t2; static JTextField t3; static JTextField t4; public void createMainWindow() { window = new JFrame("橘子苹果问题"); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setSize(700,700); window.setResizable(false); JPanel panel = new JPanel(); panel.setLayout(null); JLabel App1 = new JLabel("生产苹果者数:"); App1.setBounds(10, 500,100,25); panel.add(App1); progressbar.setStringPainted(true); progressbar.setBounds(200,640,300,30); panel.add(progressbar); progress p = new progress(myStorage); p.start(); draw1 = new Draw(myStorage); draw1.setBounds(0,0,700,300); panel.add(draw1); t1 = new JTextField(); t1.setBounds(120,500,60,25); t1.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent event) { char ch = event.getKeyChar(); if (ch '9') { event.consume(); }
}); panel.add(t1); JButton inapp1 = new JButton("增加"); inapp1.setBounds(190, 500, 60, 25); panel.add(inapp1); inapp1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (i1 0) { decreaseappleProducer(); } }); } t1.setText(String.valueOf(i1)); JLabel Org1 = new JLabel("生产橘子者数:"); Org1.setBounds(10, 550,100,25); panel.add(Org1);
t2.setBounds(120,550,60,25); t2.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent event) { char ch = event.getKeyChar(); if (ch '9') { event.consume(); } } }); panel.add(t2); JButton inorg1 = new JButton("增加"); inorg1.setBounds(190, 550, 60, 25); panel.add(inorg1); inorg1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (i2 0) { decreaseorangeProducer(); } t2.setText(String.valueOf(i2));
}); //**消费者的数目设置 苹果核橘子*/ JLabel App2 = new JLabel("消费苹果者数:"); App2.setBounds(330,500,100,25); panel.add(App2); t3 = new JTextField(); t3.setBounds(440,500, 60, 25); panel.add(t3); JButton inapp2 = new JButton("增加"); inapp2.setBounds(510,500, 60, 25); panel.add(inapp2); inapp2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (d1 0) { decreaseappleConsumer(); t3.setText(String.valueOf(d1));
} }); JLabel Org2 = new JLabel("消费橘子者数:"); Org2.setBounds(330,550,100,25); panel.add(Org2); t4 = new JTextField(); t4.setBounds(440,550, 60, 25); panel.add(t4); JButton inorg2 = new JButton("增加"); inorg2.setBounds(510,550, 60, 25); panel.add(inorg2); inorg2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (d2 0) { decreaseorangeConsumer();
} }); } /** * 这里的代码是实现了设计要求中的第三条:生产者速度可调。 */ JLabel appsp1 = new JLabel("苹果生产速度:"); appsp1.setBounds(10,400,100,25); panel.add(appsp1); final JTextField tsp1 = new JTextField(); tsp1.setBounds(120, 400, 60, 25); tsp1.setText(String.valueOf(Increaseapple.speed)); tsp1.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent event) { char ch = event.getKeyChar(); if (ch '9') { event.consume(); } } }); panel.add(tsp1); JButton appalter1 = new JButton("修改"); appalter1.setBounds(190, 400, 60, 25); panel.add(appalter1); // 在这里实现了控制生产速度的功能 appalter1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String str1 = tsp1.getText(); long i = Long.parseLong(str1); if (i = 0) {
} else if (i '9') { event.consume(); } } }); panel.add(tsp2); JButton orgalter1 = new JButton("修改"); orgalter1.setBounds(190, 450, 60, 25); panel.add(orgalter1); // 在这里实现了控制生产速度的功能
{ @Override public void actionPerformed(ActionEvent e) { String str1 = tsp2.getText(); long i = Long.parseLong(str1); if (i = 0) { Increaseapple.speed = i; } else if (i
{ event.consume(); } } }); panel.add(tsp3); JButton appalter2 = new JButton("修改"); appalter2.setBounds(440,400, 60, 25); panel.add(appalter2); // 这里实现了控制消费速度的功能 appalter2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String str2 = tsp3.getText(); long i = Long.parseLong(str2); if (i = 0) { Decreaseapple.speed = i; } else if (i
final JTextField tsp4 = new JTextField(); tsp4.setBounds(370,450, 60, 25); tsp4.setText(String.valueOf(Decreaseapple.speed)); tsp4.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent event) { char ch = event.getKeyChar(); if (ch '9') { event.consume(); } } }); panel.add(tsp4); JButton orgalter2 = new JButton("修改"); orgalter2.setBounds(440,450, 60, 25); panel.add(orgalter2); orgalter2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String str2 = tsp4.getText(); long i = Long.parseLong(str2); if (i = 0) { Decreaseorange.speed = i; } else if (i
tsp4.setText(String.valueOf(Decreaseorange.speed));
}
}
});
/**
* 这里构造了能够实现第五条要求的组件,可以显示当前线程的状态,实现了设计要求中的第五条。
*/
textArea2 = new TextArea();
textArea2.setBounds(0,300 ,350,100);
panel.add(textArea2);
textArea1 = new TextArea();
textArea1.setBounds(350,300,350,100);
panel.add(textArea1);
/**
* 这里的代码实现了设计要求第六条,定义了开始,暂停,停止三个按钮,按开始按钮线程将开始执行 生产和消费。
* 可以在运行时按暂停按钮来暂停线程的生产和消费,以便查看當前線程的狀態。按停止,则所有的线程都将被强制中止执行。
*/
JButton start = new JButton("开始");
start.setBounds(50, 600, 60, 25);
panel.add(start);
// 开始按钮
start.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Increaseapple.applepause1 = 1;
Decreaseapple.applepause2 = 1;
Increaseorange.orangepause1 = 1;
Decreaseorange.orangepause2 = 1;
DrawRect rect = new DrawRect(myStorage);
rect.start();
t1.setText(String.valueOf(i1));
t2.setText(String.valueOf(i2));
t3.setText(String.valueOf(d1));
t4.setText(String.valueOf(d2));
}
JButton sus = new JButton("暂停"); sus.setBounds(200,600,60,25); panel.add(sus); sus.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { textArea2.append("-------------------\n"); Increaseapple.applepause1 = 0; Decreaseapple.applepause2 = 0; Increaseorange.orangepause1 = 0; Decreaseorange.orangepause2 = 0; } }); JButton halt = new JButton("停止"); halt.setBounds(350,600, 60, 25); panel.add(halt); halt.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for (int a = 0; a
appledecrease[a] = null;
}
for (int a = 0; a
{
orangedecrease[a].out = true;
orangedecrease[a] = null;
}
i1 = 0;
i2 = 0;
d1 = 0;
d2 = 0;
t1.setText(String.valueOf(i1));
t2.setText(String.valueOf(i2));
t3.setText(String.valueOf(d1));
t4.setText(String.valueOf(d2));
}
});
JButton Ai = new JButton("人工智能");
Ai.setBounds(420,600, 100, 25);
Ai.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Decreaseorange.AI = 1;
Decreaseapple.AI = 1;
Increaseapple.AI = 1;
Increaseorange.AI = 1;
}
});
panel.add(Ai);
window.add(panel);
window.setVisible(true);
}
/**
* 下面这两个方法分别是往增加、开始和减少、终止生产者线程的方法。
生产者线程数组或从数组中移除。 将线程存入
* 每当调用一次该方法,就增加或减少一个生产者线程。 * * @return */ public static int increaseappleProducer() { if(i1 0) { appleincrease[i1 - 1].out = true; appleincrease[i1 - 1] = null; i1--; } return i1; } public static int decreaseorangeProducer() { if(i2 > 0) { orangeincrease[i2 - 1].out = true; orangeincrease[i2 - 1] = null; i2--;
} } return i2; public static int increaseappleConsumer() { if(d1 0) { appledecrease[d1 - 1].out = true; appledecrease[d1 - 1] = null; d1--; } return d1; } public static int decreaseorangeConsumer() { if(d2 > 0) { orangedecrease[d2 - 1].out = true; orangedecrease[d2 - 1] = null; d2--; }
return d2;
}
/**
* main方法,程序从这里执行,执行后显示主界面。所有功能在主界面中 调节。 *
* @param args
*/
public static void main(String[] args)
{
Apple mainWindow = new Apple();
mainWindow.createMainWindow();
}
}
class Draw extends JComponent
{
private MyStorage mystorage ;
public Draw(MyStorage mystorage)
{
this.mystorage = mystorage;
}
public void paint(Graphics g)
{
for(int i = 0 ;i
{
g.setColor(Color.BLACK);
g.drawRect(30*i+50, 130,30,40);
if(mystorage.pool[i] == 1)
{
g.setColor(Color.RED);
g.fillRect(30*i+51,131,29,39);
}
else if(mystorage.pool[i] == 2)
{
g.setColor(Color.ORANGE);
g.fillRect(30*i+51,131,29,39);
}
}
if(Apple.i1 > 0)
{
g.setColor(Color.BLACK);
g.drawLine(MyStorage.pointapple*30+95,130,MyStorage.pointapple*30+95,100);
g.drawLine(MyStorage.pointapple*30+95,130,MyStorage.pointapple*30+100,120);
g.drawLine(MyStorage.pointapple*30+95,130,MyStorage.pointapple*30+90,120); }
if(Apple.i2 > 0)
{
g.setColor(Color.BLACK);
g.drawLine(MyStorage.pointorange*30+35,130,MyStorage.pointorange*30+35,100);
g.drawLine(MyStorage.pointorange*30+35,130,MyStorage.pointorange*30+40,120);
g.drawLine(MyStorage.pointorange*30+35,130,MyStorage.pointorange*30+30,120); }
g.setColor(Color.PINK);
g.drawRect(50,230,40, 40);
g.fillRect(51,231 ,39,39);
char []str = {'f','a','t','h','e','r'};
Font f = new Font("serif",Font.BOLD,36);
g.setFont(f);
g.drawChars(str,0,6,100,270);
g.setColor(Color.GREEN);
g.drawRect(400,230,40,40);
g.fillRect(401,231,39,39);
char []str1 = {'m','o','t','h','e','r'};
g.drawChars(str1,0,6,450,270);
g.setColor(Color.BLUE);
g.drawRect(50,30,40,40);
g.fillRect(51,31,39,39);
char []str2 = {'s','o','n'};
g.drawChars(str2,0,3,100,70);
g.setColor(Color.YELLOW);
g.drawRect(400,30,40,40);
g.fillRect(401,31,39,39);
char []str3 = {'d','a','u','g','h','t','e','r'};
g.drawChars(str3,0,8,450,70);
}
}
class Decreaseapple extends Thread
{
private MyStorage myStorage;//保存一个MyStorage类的引用 static long speed = 2000;//speed表示消费者线程的速度 static int applepause2 = 0;//psuse2变量用来控制消费者线程的开始与暂停 boolean out = false; static int AI = 0; //定义构造方法,接收一个MyStorage类型的变量 public Decreaseapple(MyStorage myStorage) { this.myStorage = myStorage; } //run()方法调用接收的MyStorage类型的变量指向的decrease()方法,开始消费元素。 @Override public void run() { while (!out) { if(out) break; if(applepause2 == 1) { try { Thread.sleep(speed); } catch (InterruptedException e) { e.printStackTrace(); } if(AI == 1) { if(myStorage.number >= 4) { if(myStorage.applenum
Apple.t3.setText(String.valueOf(Apple.d1)); } else if(myStorage.orangenum
myStorage.decreaseapple();
}
}
}
}
}
class Decreaseorange extends Thread
{
private MyStorage myStorage;//保存一个MyStorage类的引用
static long speed = 2000;//speed表示消费者线程的速度
boolean out = false;
static int AI = 0;
public static int orangepause2 = 0;//psuse2变量用来控制消费者线程的开始与暂停
//定义构造方法,接收一个MyStorage类型的变量
public Decreaseorange(MyStorage myStorage)
{
this.myStorage = myStorage;
}
//run()方法调用接收的MyStorage类型的变量指向的decrease()方法,开始消费元素。 @Override
public void run()
{
while (!out)
{
if(orangepause2 == 1)
{
try
{
Thread.sleep(speed);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(AI == 1)
{
if(myStorage.number >= 4)
{
if(myStorage.applenum
Apple.t3.setText(String.valueOf(Apple.d1));
}
}
}
else
{
myStorage.decreaseorange();
}
}
}
}
}
class DrawRect extends Thread
{
private MyStorage myStorage;//保存一个MyStorage类的引用
public DrawRect(MyStorage myStorage)
{
this.myStorage = myStorage;
}
//run()方法调用接收的MyStorage类型的变量指向的decrease()方法,开始消费元素。 @Override
public void run()
{
while (true)
{
try
{
Apple.draw1.repaint();
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
class Increaseapple extends Thread
{
private MyStorage myStorage;//定义MyStorage类的引用。
static long speed = 2000;//定义speed变量,表示线程速度
boolean out = false; public static int applepause1 = 0;//pause1变量用来控制生产者线程的开始与暂停 static int AI = 0; //定义构造方法,接收一个MyStorage类型的变量 public Increaseapple(MyStorage myStorage) { this.myStorage = myStorage; } public void changeout() { out = !out; } //run()方法调用MyStorage类型变量指向的对象的increase()方法,开始生产元素。 @Override public void run() { while (!out) { if(out) break; if(applepause1 == 1) { try { Thread.sleep(speed); } catch (InterruptedException e) { e.printStackTrace(); } if(AI == 1) { if(myStorage.number = 16) { Apple.increaseappleConsumer(); Apple.decreaseappleProducer();
Apple.increaseorangeProducer();
myStorage.decreaseapple();
myStorage.decreaseapple();
myStorage.increaseorange();
Apple.t3.setText(String.valueOf(Apple.d1)); Apple.t1.setText(String.valueOf(Apple.i1));
Apple.t2.setText(String.valueOf(Apple.i2)); }
else if(myStorage.applenum >= 12)
{
Apple.increaseappleConsumer();
myStorage.decreaseapple();
Apple.t3.setText(String.valueOf(Apple.d1)); }
else if(myStorage.applenum
{
Apple.increaseappleConsumer();
myStorage.decreaseapple();
Apple.t3.setText(String.valueOf(Apple.d1)); }
}
}
else
{
myStorage.increaseapple();
}
}
}
}
}
class Increaseorange extends Thread
{
private MyStorage myStorage;//定义MyStorage类的引用。
static long speed = 2000;//定义speed变量,表示线程速度
boolean out = false;
static int AI = 0;
public static int orangepause1 = 0;//pause1变量用来控制生产者线程的开始与暂停
//定义构造方法,接收一个MyStorage类型的变量
public Increaseorange(MyStorage myStorage)
{
} this.myStorage = myStorage; //run()方法调用MyStorage类型变量指向的对象的increase()方法,开始生产元素。 @Override public void run() { while (!out) { if(out) break; if(orangepause1 == 1) { try { Thread.sleep(speed); } catch (InterruptedException e) { e.printStackTrace(); } if(AI == 1) { if(myStorage.number =16) { Apple.increaseorangeConsumer(); Apple.decreaseorangeProducer(); Apple.increaseappleProducer(); myStorage.decreaseorange(); myStorage.decreaseorange(); myStorage.increaseapple(); Apple.t1.setText(String.valueOf(Apple.i1)); Apple.t4.setText(String.valueOf(Apple.d2)); Apple.t2.setText(String.valueOf(Apple.i2)); } else if(myStorage.orangenum >= 12) { Apple.increaseorangeConsumer(); myStorage.decreaseorange();
Apple.t4.setText(String.valueOf(Apple.d2)); }
else if(myStorage.orangenum
{
Apple.increaseorangeConsumer(); myStorage.increaseorange();
Apple.t4.setText(String.valueOf(Apple.d2)); }
}
}
else
{
myStorage.increaseorange();
}
}
}
}
}
class MyStorage
{
//number表示动态缓冲区中元素的数量
static int number = 0;
static boolean []isFull = new boolean[20];
static int []pool = new int[20];
static char[] storage = new char[20];
static int[] applepool = new int[20];
static int[] orangepool = new int[20];
static Semaphore empty = new Semaphore(20);
static Semaphore full = new Semaphore(0);
static Semaphore apple = new Semaphore(0);
static Semaphore orange = new Semaphore(0);
static Semaphore mutex = new Semaphore(1);
static int applenum = 0;
static int orangenum = 0;
static int pointapple = -1,pointorange = 20;
public MyStorage()
{
for(int i = 0 ;i
{
isFull[i] = false;
storage[i] = '0';
pool[i] = 0;
}
}
{ empty.acquire(); mutex.acquire(); if(pointapple+1 != pointorange){ pointapple++; if(pointapple == 20) pointapple=19; isFull[pointapple] = true; applenum++; storage[pointapple] = 'A'; pool[pointapple] = 1; } String str2 = Thread.currentThread().getName(); Apple.textArea2.append("生产者生产了一个苹果" + str2 + " 运行\n"); number++; Apple.textArea1.append("仓库中的产品个数为" + number + "\n"); Apple.textArea1.append("它们是:\n"); for (int j = 0; j
} } String str2 = Thread.currentThread().getName(); Apple.textArea2.append("生产者生产了一个橘子" + str2 + " 运行\n"); number++; Apple.textArea1.append("仓库中的数字个数为" + number + "\n"); Apple.textArea1.append("它们是:\n"); for (int j = 0; j
Apple.textArea1.append("\n");
mutex.release();
empty.release();
}
public void decreaseorange()
{
orange.acquire();
full.acquire();
mutex.acquire();
String str2 = Thread.currentThread().getName();
Apple.textArea2.append("消费者" + str2 + " 运行\n");
number--;
orangenum--;
isFull[pointorange] = false;
pool[pointorange] = 0;
Apple.textArea2.append("橘子消费一个" + storage[orangepool[orangenum]] + " 运行\n");
storage[pointorange] = '0';
pointorange++;
Apple.textArea1.append("仓库中的数字个数为" + number + "\n");
Apple.textArea1.append("它们是:\n");
for (int j = 0; j
{
if(storage[j] != '0')
Apple.textArea1.append("("+j+")"+storage[j] + " ");
else
Apple.textArea1.append(" ");
}
Apple.textArea1.append("\n");
mutex.release();
empty.release();
}
}
class Semaphore{
int value;
public Semaphore(int v){
this.value = v;
}
//定义P原语操作,原语操作就是执行时不能中断,所以synchronized修饰 public synchronized void acquire(){
value--;
if(value
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void release(){
value++;
if(value
this.notify();
}
}
}
class progress extends Thread{
private MyStorage myStorage;//保存一个MyStorage类的引用
//定义构造方法,接收一个MyStorage类型的变量
public progress(MyStorage myStorage)
{
this.myStorage = myStorage;
}
//run()方法调用接收的MyStorage类型的变量指向的decrease()方法,开始消费元素。 @Override
public void run()
{
while (true)
{
try
{
int j = MyStorage.number;
Apple.progressbar.setStringPainted(true);
Apple.progressbar.setValue(j);
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
} }