import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class MainScheduler extends Thread {
//ThreadStatusVariablen
private static int pidCounter = 1;
public static final int RUN = 0;
public static final int RDY = 1;
public static final int BLK = 2;
public static final int MAXSIZE_STACK = 20;
public static int sleeptime = 100;
//Producer/Consumer Arrays
private static Producer[] prods = new Producer[50];
private static Consumer[] cons = new Consumer[50];
//Stacks und Vectoren der Threads
private static Vector<Process> readyQueue = new Vector<Process>();
public static Stack<Object> stack = new Stack<Object>();
public static Stack<Process> blklist = new Stack<Process>();
//Fenster Eigenschaften
public static Frame Output = new Frame("Producer/Consumer Programm by Christoph Hocker alias erZ");
public static TextArea output = new TextArea("Willkommen zum P/C-Lottery Programm\n" +
"Stack-Start beschreibt die anfängliche Größe \ndes Stacks." +
"Sleep-Timer beschreibt die Zeit \nzwischen eine Art Pause zwischen den \nConsumern und Producern.\n" +
"Producer/Consumer Aktionen beschrieben die \nstatistische Funktion wie oft produziert bzw \nkonsumiert wurde. " +
"Anzahl der Producer/Consumer\nbeschreibt die Anzahl der Threads von Consumern \nund Producern. " +
"Bitte achten Sie jeweils auf das\nIntervall. Sollten Fehleingaben getätigtwerden,\nso werden die Standartwerte genutzt\n" +
"Mit Start gehts los, mit Stopp ist das Spiel vorbei :-)\n\nBugreport: sichhock@hi-zigr.de\nViel Spaß.");
public static Button start = new Button("Start");
public static Button stopp = new Button("Stopp");
public static TextField value = new TextField("10");
public static TextField value2 = new TextField("100");
public static Label text = new Label("Stack-Start:");
public static Label text2 = new Label("(Interval 0 - 20)");
public static Label text3 = new Label("Sleep-Timer:");
public static Label text4 = new Label("(Interval 0 - 10000)");
public static Label ptext = new Label("Producer Aktionen:");
public static Label ptext1 = new Label("0");
public static Label ctext = new Label("Consumer Aktionen:");
public static Label ctext1 = new Label("0");
public static Label textpanz = new Label("Anzahl der Producer:");
public static Label textcanz = new Label("Anzahl der Consumer:");
public static TextField panz = new TextField("5");
public static TextField canz = new TextField("5");
public static Label panzinfo = new Label("(Interval 1 - 50)");
public static Label canzinfo = new Label("(Interval 1 - 50)");
//Statikstik Variablen
public static int pAnz = 0;
public static int cAnz = 0;
public static String showStack() {
String result="";
switch(stack.size()) {
case 0: result = "[____________________]";break;
case 1: result = "[X___________________]";break;
case 2: result = "[XX__________________]";break;
case 3: result = "[XXX_________________]";break;
case 4: result = "[XXXX________________]";break;
case 5: result = "[XXXXX_______________]";break;
case 6: result = "[XXXXXX______________]";break;
case 7: result = "[XXXXXXX_____________]";break;
case 8: result = "[XXXXXXXX____________]";break;
case 9: result = "[XXXXXXXXX___________]";break;
case 10: result = "[XXXXXXXXXX__________]";break;
case 11: result = "[XXXXXXXXXXX_________]";break;
case 12: result = "[XXXXXXXXXXXX________]";break;
case 13: result = "[XXXXXXXXXXXXX_______]";break;
case 14: result = "[XXXXXXXXXXXXXX______]";break;
case 15: result = "[XXXXXXXXXXXXXXX_____]";break;
case 16: result = "[XXXXXXXXXXXXXXXX____]";break;
case 17: result = "[XXXXXXXXXXXXXXXXX___]";break;
case 18: result = "[XXXXXXXXXXXXXXXXXX__]";break;
case 19: result = "[XXXXXXXXXXXXXXXXXXX_]";break;
case 20: result = "[XXXXXXXXXXXXXXXXXXXX]";break;
}
return result;
}
public static void fillStack(int size) {
if (size >= 0 && size <= 20 ) {
for(int i=0;i<size;i++) {
stack.add( new Object() );
}
}
}
public static void setSleeptimer(int timer) {
if(timer >= 0 && timer <= 10000) {
sleeptime = timer;
}
}
public static void lottery() {
while(true) {
int zz = new Random().nextInt(readyQueue.size());
int pidtemp = readyQueue.elementAt(zz).pid;
//Algorythmus um keine doppelten Threads aufzurufen
if(!blklist.empty()) { //Falls eine Blockliste existiert ist das aufrufen doppelter Threads erst notwendig, damit nicht zwei mal bei einer leeren Liste consumiert wird
boolean again = true;
while(again) {
again = false;
for(int i=0;i<blklist.size();i++) //Die Blockliste wird durchlaufen und der zufällig ausgewählte Thread wird geblockt
{
if(blklist.elementAt(i).pid == pidtemp) {
zz = new Random().nextInt(readyQueue.size());
pidtemp = readyQueue.elementAt(zz).pid;
again = true;
}
}
}
if(!stack.empty()) { //Nachdem der Thread nicht zwei mal hintereinander aufgerufen wird, so wird bei produzierbarer und consumierbarer Liste die Blockliste gelöscht.
blklist.clear();
}
}
synchronized(stack) {
stack.notifyAll();
}
readyQueue.elementAt(zz).state = RUN;
try { Thread.sleep(sleeptime); } catch(InterruptedException e) {System.err.println(e.getMessage()); }
}
}
public static void setProducer(int anz) {
if(!(anz>0 && anz <=50))
anz=5;
for(int i=0;i<anz;i++) {
prods[i] = new Producer(pidCounter++);
readyQueue.add(prods[i]);
}
}
public static void setConsumer(int anz) {
if(!(anz>0 && anz <=50))
anz=5;
for(int i=0;i<anz;i++) {
cons[i] = new Consumer(pidCounter++);
readyQueue.add(cons[i]);
}
}
public static void threadgo() {
for(int i = 0; i < readyQueue.size(); i++) {
//readyQueue.elementAt(i).setPriority(MAX_PRIORITY);
readyQueue.elementAt(i).start();
}
}
public static void stopAllThreads() {
for(int i = 0; i < readyQueue.size(); i++) {
try{readyQueue.elementAt(i).interrupt();}
catch(Exception ie) {/*readyQueue.elementAt(i).stop()*/;}
}
output.append("\n --- Abbruch erfolgreich --- \n");
}
public static void main(String[] args) {
Output.setSize(600, 400);
Output.setLayout(null);
Output.setVisible(true);
Output.setAlwaysOnTop(true);
Output.setResizable(false);
Output.setLocation(400, 300);
Output.addWindowListener( new CloseWindowNow() );
Output.add(output);
Output.add(start);
Output.add(text);
Output.add(value);
Output.add(value2);
Output.add(text2);
Output.add(text3);
Output.add(text4);
Output.add(ptext);
Output.add(ptext1);
Output.add(ctext);
Output.add(ctext1);
Output.add(textpanz);
Output.add(textcanz);
Output.add(panz);
Output.add(canz);
Output.add(stopp);
Output.add(panzinfo);
Output.add(canzinfo);
output.setBounds(295, 25, 300, 370);
start.setBounds(5, 343, 188, 50);
start.addActionListener( new Aktion01() );
stopp.setBounds(195, 343, 98, 50);
stopp.addActionListener( new Aktion01() );
text.setBounds(20, 40, 70, 20);
text2.setBounds(150, 40, 100, 20);
text3.setBounds(20, 70, 70, 20);
text4.setBounds(150, 70, 110, 20);
value.setBounds(100, 40, 40, 20);
value2.setBounds(100, 70, 40, 20);
ptext.setBounds(20, 130, 110, 20);
ptext1.setBounds(150, 130, 110, 20);
ctext.setBounds(20, 160, 120, 20);
ctext1.setBounds(150, 160, 120, 20);
textpanz.setBounds(20, 200, 120, 20);
textcanz.setBounds(20, 230, 120, 20);
panz.setBounds(150, 200, 30, 20);
canz.setBounds(150, 230, 30, 20);
panzinfo.setBounds(190, 200, 110, 20);
canzinfo.setBounds(190, 230, 110 ,20);
MainScheduler.stopp.setEnabled(false);
}
public static class CloseWindowNow extends WindowAdapter {
public void windowClosing( WindowEvent we) {
stack.notifyAll();
stopAllThreads();
System.exit(1);
}
}
}
------------------------------------------------------------------------------
------------------------------------------------------------------------------
import java.util.*;
public class Consumer extends Process {
Consumer(int pid) {
super(pid);
}
public void run() {
try {
while(true) {
synchronized(MainScheduler.stack) {
while(state != MainScheduler.RUN) {
MainScheduler.stack.wait();
}
}
synchronized(MainScheduler.stack) {
if(!MainScheduler.stack.isEmpty()) {
MainScheduler.stack.pop();
MainScheduler.ctext1.setText( new Integer(MainScheduler.cAnz++).toString());
}
else {
state = MainScheduler.BLK;
MainScheduler.blklist.add(this);
}
MainScheduler.output.append("Consumer "+pid+"\t"+MainScheduler.showStack()+"\n");
state = MainScheduler.RDY;
Thread.sleep(MainScheduler.sleeptime);
}
}
}
catch(InterruptedException e)
{System.err.println(e.getMessage());}
catch(EmptyStackException g) {}
}
}
---------------------------------------------------------------------
---------------------------------------------------------------------
import java.util.*;
public class Producer extends Process {
Producer(int pid) {
super(pid);
}
public void run() {
try {
while(true) {
synchronized(MainScheduler.stack) {
while(state != MainScheduler.RUN) {
MainScheduler.stack.wait();
}
}
synchronized(MainScheduler.stack) {
if(MainScheduler.stack.size() < MainScheduler.MAXSIZE_STACK) {
MainScheduler.stack.push( new Object() );
MainScheduler.ptext1.setText( new Integer(MainScheduler.pAnz++).toString());
}
else {
state = MainScheduler.BLK;
MainScheduler.blklist.add(this);
}
MainScheduler.output.append("Producer "+pid+"\t"+MainScheduler.showStack()+"\n");
state = MainScheduler.RDY;
Thread.sleep(MainScheduler.sleeptime);
}
}
}
catch(InterruptedException e)
{System.err.println(e.getMessage());}
catch(EmptyStackException g) {}
}
}
------------------------------------------------------------
------------------------------------------------------------
public class Process extends Thread {
public int pid;
public int state;
public int counter;
public Process(int pid) {
this.pid = pid;
state = MainScheduler.RDY;
counter = 0;
}
public void run() {
System.out.println("process " + pid + " started.");
try {
while(true) {
synchronized(MainScheduler.stack) {
while(state != MainScheduler.RUN) {
System.out.println("process " + pid + " sleeping.");
MainScheduler.stack.wait();
}
}
Thread.sleep(MainScheduler.sleeptime);
System.out.println("PID: " + pid + "\t" + counter++);
}
}
catch(InterruptedException e)
{
System.err.println(e.getMessage());
}
}
}
----------------------------------------------------------------------
----------------------------------------------------------------------
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Aktion01 implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == MainScheduler.start) {
MainScheduler.start.setEnabled(false);
MainScheduler.stopp.setEnabled(true);
MainScheduler.value.setEnabled(false);
MainScheduler.value2.setEnabled(false);
MainScheduler.panz.setEnabled(false);
MainScheduler.canz.setEnabled(false);
MainScheduler.output.setText("Start:\t\t");
MainScheduler.output.append(MainScheduler.showStack()+"\n");
try {MainScheduler.fillStack(Integer.parseInt(MainScheduler.value.getText()));}
catch(NumberFormatException ne) {MainScheduler.fillStack(0);}
try {MainScheduler.setSleeptimer(Integer.parseInt(MainScheduler.value2.getText()));}
catch(NumberFormatException ne) {MainScheduler.setSleeptimer(100);}
try {MainScheduler.setProducer(Integer.parseInt(MainScheduler.panz.getText()));}
catch(NumberFormatException ne) {MainScheduler.setProducer(5);}
try {MainScheduler.setConsumer(Integer.parseInt(MainScheduler.canz.getText()));}
catch(NumberFormatException ne) {MainScheduler.setConsumer(5);}
MainScheduler.threadgo();
MainScheduler.lottery();
}
if(e.getSource() == MainScheduler.stopp) {
MainScheduler.start.setEnabled(true);
MainScheduler.stopp.setEnabled(false);
MainScheduler.value.setEnabled(true);
MainScheduler.value2.setEnabled(true);
MainScheduler.panz.setEnabled(true);
MainScheduler.canz.setEnabled(true);
MainScheduler.stopAllThreads();
}
}
}