University of Scranton



The Little Book of Semaphores

Threading Learning Tool

  System Documentation

Glenn Pirozzi

Dr. Bi

12/03/2010

Submitted in partial fulfillment

Of the requirements of

CMPS 490 – Computer Projects

1 Abstract

Synchronization is a huge problem that must be addressed in any software application that uses threading, communications, or any parallel connections or computing. Most do not see the practical side to the synchronization problems; they see solutions but never implementations of said solutions. Threading is an easy way to show examples of parallel computing and the power of synchronization and its uses of semaphores. If a person would like to learn the application of synchronization through a programming language they understand; they will be able to once this project is completed. This project will incorporate python examples of the use of semaphores and synchronization from the book The Little Book of Semaphores into an understandable version of Java that will utilize threads to test said examples. Through this rewriting of the python examples; there will be a better understanding for current Computer Science Majors and any subset Majors on the real applications of synchronization solutions

Table of Contents

Abstract 2

Chapter 1 Extended Abstract 7

Context 7

Who needs it/reasons for the new system 7

Hardware/software required (user side) 7

Where it will be used/intended user group 8

Overview 8

Objectives 8

Inputs 8

Outputs 9

Outline of system features 9

Feasibility 9

Chapter 2 Justification and Feasibility 10

Chapter 3 Requirements Specifications 12

Introduction 12

System Model 13

Functional Requirements 14

User Interface Specification 16

Non-Functional Requirements 17

System Evolution 18

Chapter 4 System Design 19

Introduction 19

Main Driver 20

Architectural Design 20

Abstract Specification 21

Interface Design 22

Single Driver 23

Architectural Design 23

Abstract Specification 24

Interface Design 25

Double Driver 26

Architectural Design 26

Abstract Specification 27

Interface Design 29

Save Driver 29

Architectural Design 29

Abstract Specification 30

Interface Design 31

Cases 32

Architectural design 32

Abstract Specification 32

Algorithms Design 33

User Interface Design 59

Chapter 5 Testing Design 60

Introduction 60

Unit Testing 60

Subsystem Testing 60

System Testing, Validate Requirements 61

Acceptance Testing 62

Testing 62

Testing List 62

Requirements Traceability 64

Testing Schedule 64

Test Recording Procedures 65

Hardware and Software Requirements 65

Chapter 6 User Manual 66

Introduction 66

Introductory Manual 67

How to Use the System 67

Information on Help System 71

System Reference Manual 72

List of Services 72

Error Recovery 73

Installation Information 73

Chapter 7 Appendix 74

Cases 74

Barbershop.java 74

Barrier.java 77

Barrier_Deadlock.java 80

Barrier_Deadlock2.java 82

Building_H2O.java 85

Dining_Philosophers.java 89

Dining_Savages.java 92

Exclusive_Queue.java 94

Modus_Hall.java 97

Multicar_Roller_Coaster.java 99

Multiplex.java 103

Multiplex_noSemaphore.java 105

Multiplex_synchronized_methods.java 107

Mutex.java 108

No_Starve_Mutex.java 110

Producer_Consumer.java 112

Queue.java 114

Reader_Writer.java 116

Rendezvous.java 119

Reusable_Barrier.java 120

River_Crossing.java 123

Roller_Coaster.java 126

Sushi_Bar.java 129

Tanenbaums_Solution.java 131

The_Santa_Claus.java 133

Drivers 134

DoubleDriver.java 134

MainDriver.java 140

SaveDriver.java 141

SingleDriver.java 143

PURE 148

Barbershop.java 148

Barrier.java 149

Barrier_Deadlock2.java 150

Building_H2O.java 151

Bus_Problem.java 152

Bus_Problem_Alt.java 153

Cigarette_Smokers_Deadlock.java 154

Dining_Philosophers.java 155

Dining_Savages.java 155

Exclusive_Queue.java 156

Extended_Child_Care.java 157

Faneuil_Hall.java 158

Lightswitch.java 160

Modus_Hall.java 160

Multicar_Roller_Coaster.java 161

Multiplex.java 163

Mutex.java 163

No_Starve_Mutex.java 164

Producer_Consumer.java 165

Queue.java 165

Reader_Writer.java 166

Rendezvous 166

Rendezvous_Deadlock.java 167

Reusable_Barrier.java 167

River_Crossing.java 169

Roller_Coaster.java 170

Sushi_Bar.java 171

Sushi_Bar_Alt.java 172

Tanenbaums_Solution.java 173

The_Room_Party.java 174

The_Santa_Claus.java 175

Chapter 8 Glossary 177

Chapter 9 Index 178

Extended Abstract

1 Context

1 Who needs it/reasons for the new system

Synchronization is a huge problem that must be addressed in any software application that uses threading, communications, or any parallel connections or computing. Most do not see the practical side to the synchronization problems; they see solutions but never implementations of said solutions. Threading is an easy way to show examples of parallel computing and the power of synchronization and its uses of semaphores. If a person would like to learn the application of synchronization through a programming language they understand; they will be able to once this project is completed. This project will incorporate python examples of the use of semaphores and synchronization from the book The Little Book of Semaphores into an understandable version of Java that will utilize threads to test said examples. Through this rewriting of the python examples; there will be a better understanding for current Computer Science Majors and any subset Majors on the real applications of synchronization solutions.

2 Hardware/software required (user side)

The only thing a user will need to run the applications and simulations is a computer with the JRE 2 or Java Runtime Environment 2 as I will be developing these applications with Java 6 and I cannot guarantee that anything I use from Java 6 will be compatible with previous JRE's. I will however recommend that a user attempt to test these solutions on a computer with a processor capable of hyper threading as I will be testing threading solutions with semaphores for synchronization and without a multiprocessor to show the negative effects of non synchronization. If a user has a processor with hyper threading and or multiple processors the user will have a better chance of witnessing the problems and benefits of non synchronization and synchronization.

3 Where it will be used/intended user group

My prime goal is to make this a very straightforward and easy to read application or set of applications that can be used as teaching tools and functional experiments for semaphore use, threading, and hyper threading. These examples would also be sent back to the author of The Little Book of Semaphores, Allen B. Downey to possibly be included as a facilitator to his work in better understanding synchronization techniques. It is also my hope that any of these examples would be used or available to students at the University of Scranton who wish to understand the uses of synchronization through Java using semaphores and threads.

2 Overview

1 Objectives

I will set up plans for each example included in The Little Book of Semaphores to be converted into a Java class. After the plans are set up and written out, I will code each class with both an example with semaphores for synchronization and one without semaphores to show the difference between synchronization and non synchronization. Then after each class has been made and tested to work, I will collect them all into a package to be used. I will then create a GUI to be used with the classes for easy selection of examples.

2 Inputs

The inputs of the system are simply the user inputs of which examples they would like to see, they will be able to select individual classes to be run. Users will also be able to select the values of variables that are held in the algorithm in the Case. This is not true of all Cases but some will prompt a user for input of variables.

3 Outputs

The system will present a final output of the example that is chosen, it will also output step by step output while the class is being executed if the user requests it; although this feature may only be used on some of the sub drivers. Depending on which sub driver is selected will change what the user will see for the output. The number and types of sub drivers are still pending; as of the date of this document only two sub drivers have been made of which one has a single output screen and one has two output screens.

4 Outline of system features

I. Java classes

A. Semaphore cases

B. UI Drivers

i. GUI

a) Main Driver

b) Sub Drivers

C. Save Driver

Feasibility

This project is a conversion from one programming language to another with an added UI to help users use the examples. Because the synchronization problems and solutions are already there; I will only have to work through translation of the problems from Python to Java. The bulk of the work will come in the form of creating the GUI to drive and present the classes that are to be written.

Justification and Feasibility

One thing many students in the field of Computing Science have trouble with is the subject of Threading and Synchronization. This problem includes the ideas of synchronization and protection through the use of Semaphores. To understand their use you must have an understanding of parallel computing and grasp the idea of multiple processes accessing the same data and or resources. My objective for my application is to enable a greater understanding of Semaphore use through threading. My hopes are for a very easy to use application with a well documented and organized program files that any programmer and or user can understand the uses of Semaphores.

All students need help from time to time, my application will do just that. It will help students who need a supplement or a visual to see just how threading and Semaphores work. Semaphores are one of the more advanced topics in the field of Computing Science, to have a reliable source that can help a student better understand Semaphores and its use in threads could set some students minds at ease; even help other students achieve a higher understanding of the topic. Even students who don't necessarily need to use this application as a learning tool in the sense of seeing how Semaphores work can use this application to test out different common and uncommon cases of Semaphore solutions. The application will come with a finite number of Semaphore solutions, all of which have cases with and without semaphores to demonstrate the difference between a program being protected and unprotected. If a student wants to see just what the effects an unprotected program will have, that student can with my application. A student may also write their own cases, which I will even include in the manual what specifications it needs, as well as specifications on writing other "drivers" to be used with the application. If an example is not there for a student to use, a student may add this into the application, using the guidelines I create and just add the file to a Java package.

This application has and will take some effort to make. It has been built with the idea of expansion of its "drivers" and the addition of extra cases into the development process. Because of this, any extra features can be added at any point without as much worry to time constraint. This program can be finished on time, with all features that are planned to be included because of the previously stated. The only part of the project I can foresee giving me any type of problem is the idea of a dynamically growing application. As it is right now, the application must be manually edited if new cases are added or new drivers are added. The plan is to implement classes and methods that will handle the construction of some of the menus by looking at a list or the packages to build the application. This will make it easier for other users to add in new features.

The time frame I am looking at will be first finishing the case files on September 17th (09/17/2010). Next I will start development on the dynamic building system. The dynamic building system will take up the most time of my application and will start on September 20th (09/20/2010) and end on November 5th (11/05/2010). During the development of the dynamic building system I will also write a saving feature that will save all output. This will be from October 1st (10/01/2010) till October 22nd (10/22/2010). After that I will clean and organize the code, making it easier to create the documentation and allow users to add and alter code. This will done from November 8th (11/08/2010) to November 29th (11/29/2010). The final part of my project will be quality assurance through bug testing. This is more bug testing to make sure there is nothing the user could input to stop the program, this will not include anything the user may add. I will make sure that on my end of the application it handles new drivers and classes, but anything the user may add may interfere with other parts of the application based on what the user writes. This will be done from November 30th (11/30/2010) till an estimated December 12th (12/12/2010) or any date before then that the project may be due on. A Gantt chart will be included in this document and also in a separate excel sheet named "GlennPirozzi_Gantt.xls". [pic]

Requirements Specifications

1 Introduction

One thing many students in the field of Computing Science have trouble with is the subject of Threading and Synchronization. This problem includes the ideas of synchronization and protection through the use of Semaphores. To understand their use you must have an understanding of parallel computing and grasp the idea of multiple processes accessing the same data and or resources. My objective for my application is to enable a greater understanding of Semaphore use through threading. My hopes are for a very easy to use application that is lightweight with a well documented and organized program files that any programmer and or user can understand the uses of Semaphores.

All students need help sometimes; my application will do just that. It will help students who need a supplement or a visual to see just how threading and Semaphores work. Semaphores are one of the more advanced topics in the field of Computing Science, to have a reliable source that can help a student better understand Semaphores and its use in threads could set some students minds at ease; even help other students achieve a higher understanding of the topic. Even students who don't necessarily need to use this application as a learning tool in the sense of seeing how Semaphores work can use this application to test out different common and uncommon cases of Semaphore solutions. The application will come with a finite number of Semaphore solutions, all of which have cases with and without semaphores to demonstrate the difference between a program being protected and unprotected. If a student wants to see just what the effects an unprotected program will have, that student can with my application. A student may also write their own cases, which I will even include in the manual what specifications it needs, as well as specifications on writing other "drivers" to be used with the application. If an example is not there for a student to use, a student may add this into the application, using the guidelines I create and just add the file to a Java package.

This application has and will take some effort to make. It has been built with the idea of expansion of its "drivers" and the addition of extra cases into the development process. Because of this, any extra features can be added at any point without as much worry to time constraint. This program can be finished on time, with all features that are planned to be included because of the previously stated. The only part of the project I can foresee giving me any type of problem is the idea of a dynamically growing application. As it is right now, the application must be manually edited if new cases are added or new drivers are added. The plan is to implement classes and methods that will handled the construction of some of the menus by looking at a list or the packages itself to build the application. This will make it easier for other users to add in new features.

2 System Model

This application; as was described in chapter 1 is a very lightweight application with the ability for user created content in the form of drivers and cases. It should be noted that the application has been built with this in mind and includes documentation on how to achieve the integration of user created content. In the application the user will interact with Java classes called drivers. The drivers are the classes that run the application and specify everything from what the user sees to how the user will interact with the cases. After the drivers take the user input; although it should be noted that this is not user input as in raw data from the user through keyboard or other input, but through user selections of buttons and drop down menus, they select the appropriate case. These cases then run their processes, handling all semaphore usage and all test threading. The cases also handle output through the manipulation of a passed object through which the driver will ultimately display.

This structure, from the user to the driver to the cases insures the lightweight design of the application is fulfilled. This design structure also ensures that, even though most users of the application will be involved in looking at and creating code for the application, the three tier hierarchy of the application insures a separation of user from cases. The drivers act as a middle man handling what the user sees and how the user interacts with the cases creating a safe and stable environment. Because of this stable and easy to use environment, this application can be used for a variety of uses, not only those of threading, although that will not be its focused function, but a function that a user will have to create. That is the most powerful part of this application is the fact that there is no limit to this application, if a user wants to write a new driver, they can, and implement it into the application with minimal effort.

3 Functional Requirements

The main focus of the application is to give the user a learning environment to test cases of semaphore and thread usage in java. The application will include pre-written drivers including the main driver which launches separate drivers. Right now there are only two "sub drivers" planned which are the single driver and double driver. These are drivers which as their names suggest do a single and double output respectively. These two drivers will take the users selection of a case and execute that case. The case will then provide output back to the sub driver which will then display the output area to the user.

If you, being the user, want to include your own sub driver to demonstrate a different way of looking at an example, or even possible to do some function outside of the realm of the programs intended education of thread and semaphore usage; this can be done. The only requirements will be your ability with the Java programming language and the usage of the documentation and integration with the main driver. Although the application will dynamically build how the main driver looks either based off of an easily editable text file, or by looking into the driver package, making it completely possible to add in a new driver with little to no effort on integration into the application.

Other than the drivers being included in the program, are a plethora of classes called cases. These cases will work similarly to drivers in the respect to integration with the application. They are executed by the sub drivers and hold most if not all of the testing code. There will be included in the final application around 50 Cases; all translated from the book "The Little Book of Semaphores" by Allen B. Downey. The code they are translated from is Python into Java. This will give new users a better understanding if they are to look at the cases, as Java is a more relevant programming language to most students and new users. It will also give users a basis from which to start testing from. They will have 50 cases to test and see the difference between protected and un-protected threads, as well as a greater understanding of what they themselves could create and run. Although a great focus of the development of this application is the cases and the translation, a large focus will also be placed on the potential of user created content and the ability of a user to learn from this tool and be able significantly understand the uses of semaphores and threads.

4 User Interface Specification

As described above the application takes on a three tier structure. It takes a three tier stricter in both design and implementation. It is designed with the idea that a user starts the main driver in which they can select a sub driver. With that sub driver they can then select a case or cases to run with multiple options for output. It is also a three tier in implementation in that the user, one tier, interacts with the drivers, the second tier, which ultimately executes the cases. The look and feel of each tier can be a bit different, and sometimes the same.

The user will from the outside on a pure: only using this application with what is written and what is provided, will interact and see only the drivers and sub drivers. The main driver is a small window, rectangle in shape. The rectangle of the main driver has a higher height than its width. It includes buttons, all buttons from the top going down in one column are the sub driver buttons and will on user press, execute the sub drivers. The last button in the column is the exit button, of which will exit both the main driver and any sub drivers currently opened.

The sub drivers are all slightly similar to each other. The first, the single driver is a larger rectangular window, similar in shape structure to the main driver. It includes a top centered white output window, with a drop down selection under the output window and a run button next to the drop down window to the right of it and under the output window. The user will select what they want to test from the list of cases, then they will hit run to see the results of that particular case. The second driver, the double driver, is very close to the single driver, except that it includes two output windows and under each output window a drop down selection. Each drop down selection corresponds to the window it is under. The run button is slightly off set from the single driver due to the addition of a second drop down selection. It should also be noted that a save selection may be included as well as other "tool" features. These will be included in the final application, although they may not all work, they will however at least give the user an explanation of what there functions will be once they are written with future updates.

What the user sees as output varies depending on which case is selected. Each case is unique and will have slightly to massively varying degrees of output, all shown in the output window of a sub driver. Because of this an explanation of what the user will see cannot be explained. However it can be explained that when the user hits the run button, they will see the word run displayed in the output window before the case is executed. This output of run is handled by the sub driver as to not have to worry about the problems of synchronization and protection.

5 Non-Functional Requirements

The only thing a user will need to run the applications and cases is a computer with the JRE 2 or Java Runtime Environment 2 as I will be developing these applications with Java SE 6 and I cannot guarantee that anything I use from Java SE 6 will be compatible with previous JRE's. I will however recommend that a user attempt to test these solutions on a computer with a processor capable of hyper threading or at least a multiprocessor computer as I will be testing threading solutions with semaphores for synchronization and without a multiprocessor, users may not be able to see the negative effects of non synchronization. If a user has a processor with hyper threading and or multiple processors the user will have a better chance of witnessing the problems and benefits of non synchronization and synchronization.

Every case used in this program has its own response time, which is even affected by the hardware used. This application will be tested on many different platforms, including windows and Linux (Ubuntu v10.10). It will also be tested on a net book with a 1.83 GHz Intel atom processor with 1GB of DDR 3 memory; it will also be tested on a desktop with a 2.66 GHz Intel core i7 processor with 6GB of DDR 3 memory. I will be able to confirm that this application will run on most if not all hardware that falls between these two specified hardware setups. The only issue currently seen is lower resolution screens on Ubuntu 10.10 do not show font at correct size.

All the code used in the application will be uniform in how it is setup. Each case uses the same constructor parameters making it easy to write other cases and implement them. Each sub driver may be written in any manner due to the fact that the main driver only executes the sub driver, the sub driver does not receive any parameters from the main driver. The documentation of the program will have detailed instructions on how to add new sub drivers and cases. It will explain the needed requirements of integration into the application. The entire application will have uniform comments explaining uses and choices for code and will also explain integration practices for the application. The goal is to create a user friendly code atmosphere where changes and new features may be added without damaging the overall application.

6 System Evolution

The only assumption that has been made for the application is the fact that each case will receive only an object, to be more precise a JText area. If a user created driver does not take this into account, all previously written cases will have to be changed for the new parameters that a sub driver sends to be accepted. Any new user created cases can accept any parameters they so choose, although this will be discouraged as they cannot easily be officially included into future releases of application. The other assumption made is that as of now, no official sub drivers will be written with the idea that a user will be able to input any data other than a selection from a list or the press of buttons. Users will not be able to submit any text input or any files directly from the sub drivers.

As stated throughout the paper, the application is being written to dynamically build both the main driver and the list of cases. This way all user created sub drivers and cases can be integrated into the application. This system design also makes it easy for future updates as any new features can be written into an old sub driver without worry of incompatibility with user created content; new content can also be added without worry in the form of new sub drivers and new cases. The dynamic structure of the application ensures that future releases and support are possible, as well as personal user maintenance and additions. These are all welcomed as long as the user respects the documentation that will be provided with the application.

System Design

1 Introduction

The application, as described in earlier chapters, is based off of the algorithms in the book by Allen B. Downey, “The Little Book of Semaphores.” Almost all algorithms used in the application are taken directly from this book and so will be explained thoroughly throughout this section. A quick synopsis of the system shows a three tier hierarchy for the entire system design. The application starts with the Main Driver. The Main Driver is the launcher for all other features of the application and is crucial to the success of the application. If for any reason the Main Driver fails, the user will not be able to launch any Sub Drivers that make up the bulk of the User Interface. The second tier or the Sub Drivers are the bulk of the User Interface. The Sub Drivers run all features of the application. These features include the options for running Cases, which Cases to run and how output should be presented. There are a few different types of Sub Drivers, those that are visible and those that are invisible. Visible are Sub Drivers that operate a User Interface and will interact directly with the user. Invisible are Sub Drivers that operate without any interface for the user to act directly with the Sub Drivers. Users may know of the existence of invisible Sub Drivers, but can only influence these Sub Drivers indirectly through other Sub Drivers. The last tier is the use cases or Cases. These are the algorithms included in “The Little Book of Semaphores” and are the bulk of the running operations of the application. They allow the user to explore the ideas and functionality of the algorithms and the application supplies a test environment for the algorithms. Each Case class is started from a Sub Driver, where many different features can be changed, such as the way output is handled. With the three tier hierarchy in place, it makes modifications to the application simple, it also makes user content easy to implement.

2 Main Driver

1 Architectural Design

The Main Driver is the Java class that holds the main method. This class is the main application program that starts the application and for which the user will start any important functions in. The Main Driver window is 200 pixels wide by 350 pixels long. The Main Driver is composed of three buttons currently, with an estimated five buttons by the time that development is complete. Four buttons are currently planned as the Sub Driver buttons with one button being the exit button. The three buttons that are currently there are the Single button, Double button, and Exit button. Each button is 80 pixels wide by 30 pixels long. Currently the Driver uses the default layout, meaning that it uses a uniform "Java" look to it, it is planned that this may change to a windows look, it is not determined if this will be uniform.

[pic][pic]

2 Abstract Specification

1 Single Button

The Single button is an event driven button utilizing the JButton class of the Java Swing environment. This button, when pressed activates an event through the ActionListener where it launches the class SingleDriver.class. The button's title is "Single" with a scroll over text of "Single text area threading case test." This button is situated 50 pixels from the left and 100 pixels from the top.

2 Double Button

The Double button is an event driven JButton class of the Java Swing environment. This button, when pressed activates an event through the ActionListener where it launches the class DoubleDriver.class. The button's title is "Double" with a scroll over text of " Double text area threading case test." This button is situated 50 pixels from the left and 150 pixels from the top.

3 Exit Button

The Exit button is also an event driven JButton class of the Java Swing environment. However when this button is pressed although it does activate an event with the ActionListener class, it does not launch another class. The event instead launches the command "System.exit(0);" This command when given the parameter 0, will kill the process and thus exit the application. This button does not have a scroll over text. The button is situated 50 pixels from the left and 250 from the top.

3 Interface Design

1 Single Button

The Single Button is a standalone button. Although it resembles the other buttons in the group, its button press will not affect the Main Driver other than launching its Sub Driver. Once the Sub Driver is launched the Main Driver will continue on where the button can be pressed again and launch another object of the Sub Driver. This is not another instance as it creates another declaration of the Sub Driver class.

2 Double Button

The Double Button is a standalone button. Even though it also resembles the other buttons in the group, its button press will not affect the Main Driver other than launching its Sub Driver. Once the Double Driver is launched the Main Driver will continue on where the button can be pressed again and launch another object of the Sub Driver. This is not another instance as it creates another declaration of the Sub Driver class.

3 Exit Button

The Exit Button is unlike the first two buttons in that it is not a standalone button. Different from the other two buttons is in its ability to exit out of the Main Driver. This does affect the Main Driver, it also affects the Sub Drivers because if the Main Driver is closed the Sub Drivers are also closed, however the System.exit(0) will close out of the entire application regardless of the fact that in that process the Main Driver is closed.

3 Single Driver

1 Architectural Design

The Single Driver is the first of two Sub Drivers that are implemented through button presses in the Main Driver. The Single Driver is also the first of three of the Visible Sub Drivers. The Single Driver is a Java class with all of its UI declarations housed in the constructor of the class. The window is 500 pixels wide by 600 pixels long. It consists of a JTextArea with a JScrollPane of 400 pixels wide by 400 pixels long, a JComboBox of 150 pixels wide by 20 pixels long, and a Run button of 80 pixels wide by 30 pixels long. The Single Driver also includes a menu bar with the drop down menu File that consists of Save and Close, all of which are 20 pixels long. What the user cannot see is the switch used to determine the user selection on the combo box as well as the list used to populate the combo box.

[pic][pic]

2 Abstract Specification

1 JTextArea

This houses all output from the Case that is selected by the user. The Text Area is an object that is sent to a Case to be output to. Output is handled by the case leaving the Single Driver ready to handle another user input. It also saves the Single Driver the trouble of needing to accept anything back from the Case. The reason for this is that every case has a different output and trying to determine how to handle this output should be handled independently from the Single Driver. The Text Area starts 40 pixels from the left and 21 pixels from the top.

2 JComboBox

All user selections for Cases are stored inside the Combo Box. The Combo Box is given a String in which to display all available Cases that the user can select. If a selection is selected the Combo Box sets a variable to that corresponding selection for which the switch will use. The Combo Box sits 50 pixels from the left and 450 pixels from the top.

3 Run Button

Run button is an event driven button utilizing the JButton class of the Java Swing environment. This button, when pressed activates an event through the ActionListener where it launches the method run. The button's title is "Run." This button is situated 250 pixels from the left and 450 pixels from the top.

4 Menu Bar

The menu bar is an event driven menu utilizing the JMenuBar class of the Java Swing environment. This menu, when the cursor is placed over it will open up to show two selections. These two selections are Save and Close. The Save and Close are both JMenuItems with Action Listeners that function exactly like the JButtons. Only the Save Menu Item has an "active" Action Listener which when activated will open the SaveDriver.class. The Menu Bar sits 0 pixels from the left and 0 pixels down.

5 Switch

The Switch is located in the run method of the class. It holds a case for each Case that starts at zero. When the method run is accessed it accepts both an integer called "index" and a JTextArea called "a". The Switch then uses the integer index to determine which case is to be accessed thus selecting the correct Case.

3 Interface Design

1 JTextArea

JTextArea creates a JTextArea that will be passed to the Cases. When a JTextArea is passed to a Case that Case is allowed to output to the specific JTextArea. Before the JTextArea is passed to a Case it is passed into the method run in which will be passed into the constructor of each Case.

2 JComboBox

The JComboBox is used to make the selection for the Switch. This is done through the variable Index. The Variable index can be any number from 0 to n - 1 where n is the amount of Cases implemented. The Variable index from the JComboBox is passed to the method run where it will be utilized by the Switch.

3 Run Button

The Run button accesses the method run. It passes to the method run the index and JTextArea. It does not directly affect anything within the Single Driver other than starting the method run.

4 Menu Bar

Is used as access to the Save Driver and as another way to close out the Single Driver. The Save MenuItem is used to access the Save Driver while the Close MenuItem is used to close out of the Single Driver. If the Save Driver is accessed it is sent the JTextArea.

4 Double Driver

1 Architectural Design

The Double Driver is the last of two Sub Drivers that are implemented through button presses in the Main Driver. The Double Driver is also the second of three of the Visible Sub Drivers. The Double Driver is a Java class with all of its UI declarations housed in the constructor of the class. The window is 500 pixels wide by 600 pixels long. It consists of two JTextArea with a JScrollPane of 200 pixels wide by 400 pixels long, two JComboBox of 150 pixels wide by 20 pixels long, and a Run button of 80 pixels wide by 30 pixels long. The Double Driver also includes a menu bar with the drop down menu File that consists of Save and Close, all of which are 20 pixels long. What the user cannot see is the switch used to determine the user selection on the combo box as well as the list used to populate the combo boxes. The Double Driver also utilizes threads to achieve a concurrent execution of two Cases instead of one. This means that each thread can access the switch, although not at the same time to ensure that synchronization is achieved.

[pic][pic]

2 Abstract Specification

1 JTextArea

This houses all output from the Case that is selected by the user. The Text Area is an object that is sent to a Case to be output to. Output is handled by the case leaving the Single Driver ready to handle another user input. It also saves the Double Driver the trouble of needing to accept anything back from the Case. The reason for this is that every case has a different output and trying to determine how to handle this output should be handled independently from the Double Driver. The first Text Area starts 40 pixels from the left and 21 pixels from the top. The second Text Area starts 250 pixels from the left and 21 pixels from the top.

2 JComboBox

All user selections for Cases are stored inside the Combo Box. The Combo Box is given a String in which to display all available Cases that the user can select. If a selection is selected the Combo Box sets a variable to that corresponding selection for which the switch will use. The first Combo Box sits 50 pixels from the left and 450 pixels from the top. The second Combo Box sits 200 pixels from the left and 450 pixels form the top.

3 Run Button

Run button is an event driven button utilizing the JButton class of the Java Swing environment. This button, when pressed activates an event through the ActionListener where it launches the method run. The button's title is "Run." This button is situated 250 pixels from the left and 450 pixels from the top.

4 Menu Bar

The menu bar is an event driven menu utilizing the JMenuBar class of the Java Swing environment. This menu, when the cursor is placed over it will open up to show two selections. These two selections are Save and Close. The Save and Close are both JMenuItems with Action Listeners that function exactly like the JButtons. Only the Save Menu Item has an "active" Action Listener which when activated will open the SaveDriver.class. The Menu Bar sits 0 pixels from the left and 0 pixels down.

5 Switch

The Switch is located in the run method of the class. It holds a case for each Case that starts at zero. When the method run is accessed it accepts both an integer called "index" and a JTextArea called "a". The Switch then uses the integer index to determine which case is to be accessed thus selecting the correct Case.

3 Interface Design

1 JTextArea

JTextArea creates a JTextArea that will be passed to the Cases. When a JTextArea is passed to a Case that Case is allowed to output to the specific JTextArea. Before the JTextArea is passed to a Case it is passed into the method run in which will be passed into the constructor of each Case.

2 JComboBox

The JComboBox is used to make the selection for the Switch. This is done through the variable Index. The Variable index can be any number from 0 to n - 1 where n is the amount of Cases implemented. The Variable index from the JComboBox is passed to the method run where it will be utilized by the Switch.

3 Run Button

The Run button accesses the method run. It passes to the method run the index and JTextArea. It does not directly affect anything within the Double Driver other than starting the method run.

4 Menu Bar

Is used as access to the Save Driver and as another way to close out the Double Driver. The Save MenuItem is used to access the Save Driver while the Close MenuItem is used to close out of the Double Driver. If the Save Driver is accessed it is sent both JTextAreas.

5 Save Driver

1 Architectural Design

The Save Driver is accessed from both the Single Driver and the Double Driver. Its purpose is to save the output of the JTextArea to a file specified by the user. The Save Driver just like the other two Visible Drivers is a Java class with all of its UI declarations housed in the constructor of the class. The difference being though that the other classes do not just create the object for the Save Driver and then let the Save Driver handle itself. After the Save Driver is declared and instantiated a method called "savefunction" must be called. The method "savefunction" is overloaded, one with a single passed JTextArea and one with two JTextArea's passed. The window of the Save Driver is 450 pixels wide by 200 pixels long. It consists of three objects. The first is the JButton, "Save", of which is 80 pixels wide by 30 pixels long. The second is a JLabel which includes the words "Enter in file name: ." The third is the JTextField which is 120 pixels wide by 10 pixels long.

[pic][pic]

2 Abstract Specification

1 Save Button

Save button is an event driven button utilizing the JButton class of the Java Swing environment. This button, when pressed activates an event through the ActionListener where it declares and instantiates both a FileWriter and BufferedWriter. Both of these The button's title is "Run." This button is situated 250 pixels from the left and 450 pixels from the top.

2 JLabel

The JLabel is used to denote to the user what the JTextArea is used for. In this case the JLabel includes the String "Enter in file name: ." The label is situated 150 pixels from the left and 20 pixels from the top.

3 JTextField

The JTextField is used to store input from the user denoting the file that the user wants the output of the JTextArea to be placed in. As of now the JTextField does not hold any restrictions against a users input. The user must include their own extension when naming the file they are going to save. The JTextField is situated 300 pixels from the left and 20 pixels from the top.

3 Interface Design

1 Save Button

The Save button interacts with the FileWriter and BufferedWriter. They take the input from the JTextField and apply it to the name of the file they are writing the JTextArea to. The Save button will not at this time close out of the window when done saving, this must be manually done by the user.

2 JTextField

JtextField is used by the FileWriter and BufferedWriter to name the file they are writing to. However the user inputs the file name is how the writers will write it as. This means that the user could conceivably save a file as both a .txt or as a .doc. If the user feels they could save it as a .jpg or .exe if they so choose.

6 Cases

1 Architectural design

Each Case is a use case based off of an algorithm from "The Little Book of Semaphores." All use cases from the book are in python. They are then translated to Java for use in the application. Each Case is implemented with Semaphore usage, however there are also Cases implemented with Synchronized Methods. The Cases are Java classes with no user interface. They are not Sub Drivers but their own entity. Each Case when created accepts a single variable of a JTextArea for output. Each Case also includes a "Logging Thread" of which will log all the output of the Case.

[pic]

2 Abstract Specification

1 Algorithm

The Algorithm taken from the book "The Little Book of Semaphores" may constitute any classical and or non classical synchronization algorithm. It may also be noted that all the algorithms included with the base application are from "The Little Book of Semaphores" however users may make their own Cases in which use different algorithms from different sources.

2 Logging Thread

The Logging Thread is an extra thread created to handle all output from the Case. Its purpose is to attempt to minimize interruption from output to the JTextArea as well as keep synchronization true for the JTextArea. The way it achieves this is by using the ConcurrentLinkedQueue class. This queue is thread safe and therefore cannot be accessed by more than one thread at a time. As every thread places an output into the queue the thread will take this output and add it to the JTextArea. In between each add to the JTextArea the Logging Thread will sleep for an amount of time before waking up to accept the next output. When a thread ends it will output the String "END." When the Logging Thread receives this String "END" it will increment a counter which will exit the thread when it reaches the same number as threads that were running in the Case. This ensures minimal interruptions from the output.

3 Algorithms Design

1 Signaling

This is the most basic algorithm. It is the idea that one thread sends a signal to another thread to indicate when an event has occurred. This makes it possible to guarantee that a section of code in one thread will run before another thread. This algorithm uses a semaphore named sem with an initial value of 0. Thread A and Thread B have access to it.

Thread A

1 statement a1

2 sem.signal()

Thread B

1 sem.wait()

2 statement b1

2 Rendezvous

This is a generalization of the Signaling algorithm, this makes it so that it can work both ways. The idea behind this is that two threads will meet at a point of execution, and neither will be allowed to proceed until both have arrived. This Algorithm uses two semaphores, aArrived and bArrived both set to zero.

Thread A

1 statement a1

2 aArrived.signal()

3 bArrived.wait()

4 statement a2

Thread B

1 statement b1

2 bArrived.signal()

3 aArrived.wait()

4 statement b2

3 Mutex

This is an algorithm used for mutual exclusion. The mutex will guarantee that only one thread may access the a shared resource at a time. The idea behind this is that only one thread may access the mutex at any time, therefore only one thread may do what it has to do with the shared resource at a time. In this algorithm both threads will used a shared variable count. They will also use the semaphore mutex that is initialized to 1.

Thread A

mutex.wait()

# critical section

count = count + 1

mutex.signal()

Thread B

mutex.wait()

# critical section

count = count + 1

mutex.signal()

4 Multiplex

This is a generalization of the mutex algorithm to allow more than two threads to use the algorithm at once. For this algorithm to work, the semaphore mutex must be set to a value n. This value n is the maximum number of allowed threads. If the value of the semaphore reaches zero the semaphore will block the next thread that tries to access the critical section. When a thread leaves, the value of the semaphore is incremented allowing another thread to enter.

1 multiplex.wait()

2 critical section

3 multiplex.signal()

5 Barrier

Is the generalization of the rendezvous solution to allow multiple threads. This algorithm assumes that there are n threads and that this is stored in a variable n. When the first n - 1 threads arrive they should block until the nth thread arrives, when this happens all threads will be able to proceed. The variables used in this algorithm are n which is the number of threads. A count which is set to 0 which keeps track of how many threads have arrived. The semaphore mutex initialized to 1 and the semaphore barrier initialized to 0.

1 rendezvous

2

3 mutex.wait()

4 count = count + 1

5 mutex.signal()

6

7 if count == n: barrier.signal()

8

9 barrier.wait()

10 barrier.signal()

11

12 critical point

6 Reusable Barrier

A barrier that will lock itself after all the threads have passed through. The algorithm uses the idea of turnstiles to allow access. These are built into semaphores called turnstile which is initialized to 0 and turnstile2 which is initialized to 1. There is also the semaphore mutex initialized to 1.

# rendezvous

2

3 mutex.wait()

4 count += 1

5 if count == n:

6 turnstile2.wait() # lock the second

7 turnstile.signal() # unlock the first

8 mutex.signal()

9

10 turnstile.wait() # first turnstile

11 turnstile.signal()

12

13 # critical point

14

15 mutex.wait()

16 count -= 1

17 if count == 0:

18 turnstile.wait() # lock the first

19 turnstile2.signal() # unlock the second

20 mutex.signal()

21

22 turnstile2.wait() # second turnstile

23 turnstile2.signal()

7 Queue

This algorithm uses semaphores as a queue. For this algorithm it uses the idea that both a leader and a follower need to be present to continue. This is because the value of a semaphore should never be positive in this example of a queue. The reason for this is that it should not be possible to signal unless there is a thread waiting. We should create two semaphores a leaderQueue initialized to 0 and a followerQueue initialized to 0. This algorith goes off of the idea of a ballroom dance in which a leader must be accompanied by a follower, thus the call to dance().

Code for Leaders:

1 followerQueue.signal()

2 leaderQueue.wait()

3 dance()

Code for Followers:

1 leaderQueue.signal()

2 followerQueue.wait()

3 dance()

8 Exclusive Queue

This algorith adds the constraint to Queue that each leader can invoke dance concurrently with only one follower, and vice versa. As Downey states "You got to dance with the one that brought you." This algorithm uses two variables leaders and followers both set to 0. It also includes four semaphores: mutex initialized to 1, leaderQueue initialized to 0, followerQueue initialized to 0, and rendezvous initialized to 0.

Code for Leaders:

1 mutex.wait()

2 if followers > 0:

3 followers--

4 followerQueue.signal()

5 else:

6 leaders++

7 mutex.signal()

8 leaderQueue.wait()

9

10 dance()

11 rendezvous.wait()

12 mutex.signal()

Code for Followers:

1 mutex.wait()

2 if leaders > 0:

3 leaders--

4 leaderQueue.signal()

5 else:

6 followers++

7 mutex.signal()

8 followerQueue.wait()

9

10 dance()

11 rendezvous.signal()

9 Fifo Queue

This adds the idea that the first thread to arrive at a semaphore should be the first to enter the semaphore and so forth. This solution uses two semaphores: mySem initialized to 0 and mutex initialized to 1. It also uses a queue called queue. There is also a mutex semaphore.

class Fifo:

2 def __init__(self):

3 self.queue = Queue()

4 self.mutex = Semaphore(1)

5

6 def wait():

7 self.mutex.wait()

8 self.queue.add(mySem)

9 self.mutex.signal()

10 mySem.wait()

11

12 def signal():

13 self.mutex.wait()

14 sem = self.queue.remove()

15 self.mutex.signal()

16 sem.signal()

For the more advanced algorithms short summaries will not be given, instead a list of variables and the solutions will be given instead.

10 Producer-Consumer

Variables:

1 mutex = Semaphore(1)

2 items = Semaphore(0)

3 local event

Producer Solution:

1 event = waitForEvent()

2 mutex.wait()

3 buffer.add(event)

4 mutex.signal()

5 items.signal()

Consumer Solution:

1 items.wait()

2 mutex.wait()

3 event = buffer.get()

4 mutex.signal()

5 event.process()

11 Readers-Writers

Variables:

1 int readers = 0

2 mutex = Semaphore(1)

3 roomEmpty = Semaphore(1)

Writers Solution:

1 roomEmpty.wait()

2 critical section for writers

3 roomEmpty.signal()

Readers Solution:

1 mutex.wait()

2 readers += 1

3 if readers == 1:

4 roomEmpty.wait() # first in locks

5 mutex.signal()

6

7 # critical section for readers

8

9 mutex.wait()

10 readers -= 1

11 if readers == 0:

12 roomEmpty.signal() # last out unlocks

13 mutex.signal()

12 No-Starve Mutex

Variables:

1 room1 = room2 = 0

2 mutex = Semaphore(1)

3 t1 = Semaphore(1)

4 t2 = Semaphore(0)

Morris's algorithm:

mutex.wait()

2 room1 += 1

3 mutex.signal()

4

5 t1.wait()

6 room2 += 1

7 mutex.wait()

8 room1 -= 1

9

10 if room1 == 0:

11 mutex.signal()

12 t2.signal()

13 else:

14 mutex.signal()

15 t1.signal()

16

17 t2.wait()

18 room2 -= 1

19

20 # critical section

21

22 if room2 == 0:

23 t1.signal()

24 else:

25 t2.signal()

13 Dining Philosophers

Variables and Definitions :

1 def left(i): return i

2 def right(i): return (i + 1) % 5

1 forks = [Semaphore(1) for i in range(5)]

Solution:

1 def get_forks(i):

2 footman.wait()

3 fork[right(i)].wait()

4 fork[left(i)].wait()

5

6 def put_forks(i):

7 fork[right(i)].signal()

8 fork[left(i)].signal()

9 footman.signal()

14 Tanenbaum's Solution

This solution is for the dining philosophers

Variables:

1 state = [’thinking’] * 5

2 sem = [Semaphore(0) for i in range(5)]

3 mutex = Semaphore(1)

Solution:

1 def get_fork(i):

2 mutex.wait()

3 state[i] = ’hungry’

4 test(i)

5 mutex.signal()

6 sem[i].wait()

7

8 def put_fork(i):

9 mutex.wait()

10 state[i] = ’thinking’

11 test(right(i))

12 test(left(i))

13 mutex.signal()

14

15 def test(i):

16 if state[i] == ’hungry’ and

17 state (left (i)) != ’eating’ and

18 state (right (i)) != ’eating’:

19 state[i] = ’eating’

20 sem[i].signal()

15 Cigarette Smokers

Variables:

1 isTobacco = isPaper = isMatch = False

2 tobaccoSem = Semaphore(0)

3 paperSem = Semaphore(0)

4 matchSem = Semaphore(0)

Pushers Code:

1 tobacco.wait()

2 mutex.wait()

3 if isPaper:

4 isPaper = False

5 matchSem.signal()

6 elif isMatch:

7 isMatch = False

8 paperSem.signal()

9 else:

10 isTobacco = True

11 mutex.signal()

Smoker with Tobacco:

1 tobaccoSem.wait()

2 makeCigarette()

3 agentSem.signal()

4 smoke()

16 The Dining Savages

Variables:

1 servings = 0

2 mutex = Semaphore(1)

3 emptyPot = Semaphore(0)

4 fullPot = Semaphore(0)

Cook Code:

1 while True:

2 emptyPot.wait()

3 putServingsInPot(M)

4 fullPot.signal()

Savage Code:

while True:

2 mutex.wait()

3 if servings == 0:

4 emptyPot.signal()

5 fullPot.wait()

6 servings = M

7 servings -= 1

8 getServingFromPot()

9 mutex.signal()

10

11 eat()

17 Barbershop

Variables:

1 customers = 0

2 mutex = Semaphore(1)

3 customer = Semaphore(0)

4 barber = Semaphore(0)

Customer Code:

1 mutex.wait()

2 if customers == n+1:

3 mutex.signal()

4 balk()

5 customers += 1

6 mutex.signal()

7

8 customer.signal()

9 barber.wait()

10 getHairCut()

11

12 mutex.wait()

13 customers -= 1

14 mutex.signal()

Barber Code:

1 customer.wait()

2 barber.signal()

3 cutHair()

18 Hilzer's Barbershop

Variables:

1 customers = 0

2 mutex = Semaphore(1)

3 standingRoom = Fifo(16)

4 sofa = Fifo(4)

5 chair = Semaphore(3)

6 barber = Semaphore(0)

7 customer = Semaphore(0)

8 cash = Semaphore(0)

9 receipt = Semaphore(0)

Customer Code:

1 mutex.wait()

2 if customers == 20:

3 mutex.signal()

4 exitShop()

5 customers += 1

6 mutex.signal()

7

8 standingRoom.wait()

9 enterShop()

10

11 sofa.wait()

12 sitOnSofa()

13 standingRoom.signal()

14

15 chair.wait()

16 sitInBarberChair()

17 sofa.signal()

18

19 customer.signal()

20 barber.wait()

21 getHairCut()

22

23 pay()

24 cash.signal()

25 receipt.wait()

26

27 mutex.wait()

28 customers -= 1

29 mutex.signal()

30

31 exitShop()

Barber Code:

1 customer.wait()

2 barber.signal()

3 cutHair()

4

5 cash.wait()

6 acceptPayment()

7 receipt.signal()

19 Santa Claus

Variables:

1 elves = 0

2 reindeer = 0

3 santaSem = Semaphore(0)

4 reindeerSem = Semaphore(0)

5 elfTex = Semaphore(1)

6 mutex = Semaphore(1)

Santa Code:

1 santaSem.wait()

2 mutex.wait()

3 if reindeer == 9:

4 prepareSleigh()

5 reindeerSem.signal(9)

6 else if elves == 3:

7 helpElves()

8 mutex.signal()

Reindeer Code:

1 mutex.wait()

2 reindeer += 1

3 if reindeer == 9:

4 santaSem.signal()

5 mutex.signal()

6

7 reindeerSem.wait()

8 getHitched()

Elves Code:

1 elfTex.wait()

2 mutex.wait()

3 elves += 1

4 if elves == 3:

5 santaSem.signal()

6 else

7 elfTex.signal()

8 mutex.signal()

9

10 getHelp()

11

12 mutex.wait()

13 elves -= 1

14 if elves == 0:

15 elfTex.signal()

16 mutex.signal()

20 Building H2O

Variables:

1 mutex = Semaphore(1)

2 oxygen = 0

3 hydrogen = 0

4 barrier = Barrier(3)

5 oxyQueue = Semaphore(0)

6 hydroQueue = Semaphore(0)

Oxygen Code:

1 mutex.wait()

2 oxygen += 1

3 if hydrogen >= 2:

4 hydroQueue.signal(2)

5 hydrogen -= 2

6 oxyQueue.signal()

7 oxygen -= 1

8 else:

9 mutex.signal()

10

11 oxyQueue.wait()

12 bond()

13

14 barrier.wait()

15 mutex.signal()

Hydrogen Code:

1 mutex.wait()

2 hydrogen += 1

3 if hydrogen >= 2 and oxygen >= 1:

4 hydroQueue.signal(2)

5 hydrogen -= 2

6 oxyQueue.signal()

7 oxygen -= 1

8 else:

9 mutex.signal()

10

11 hydroQueue.wait()

12 bond()

13

14 barrier.wait()

21 River Crossing

Variables:

1 barrier = Barrier(4)

2 mutex = Semaphore(1)

3 hackers = 0

4 serfs = 0

5 hackerQueue = Semaphore(0)

6 serfQueue = Semaphore(0)

7 local isCaptain = False

Solution:

1 mutex.wait()

2 hackers += 1

3 if hackers == 4:

4 hackerQueue.signal(4)

5 hackers = 0

6 isCaptain = True

7 elif hackers == 2 and serfs >= 2:

8 hackerQueue.signal(2)

9 serfQueue.signal(2)

10 serfs -= 2

11 hackers = 0

12 isCaptain = True

13 else:

14 mutex.signal() # captain keeps the mutex

15

16 hackerQueue.wait()

17

18 board()

19 barrier.wait()

20

21 if isCaptain:

22 rowBoat()

23 mutex.signal() # captain releases the mutex

22 Roller Coaster

Variables:

1 mutex = Semaphore(1)

2 mutex2 = Semaphore(1)

3 boarders = 0

4 unboarders = 0

5 boardQueue = Semaphore(0)

6 unboardQueue = Semaphore(0)

7 allAboard = Semaphore(0)

8 allAshore = Semaphore(0)

Car Code:

1 load()

2 boardQueue.signal(C)

3 allAboard.wait()

4

5 run()

6

7 unload()

8 unboardQueue.signal(C)

9 allAshore.wait()

Passenger Code:

1 boardQueue.wait()

2 board()

3

4 mutex.wait()

5 boarders += 1

6 if boarders == C:

7 allAboard.signal()

8 boarders = 0

9 mutex.signal()

10

11 unboardQueue.wait()

12 unboard()

13

14 mutex2.wait()

15 unboarders += 1

16 if unboarders == C:

17 allAshore.signal()

18 unboarders = 0

19 mutex2.signal()

23 Multi-car Roller Coaster

Variables and Definitions (some variables carry over from last problem):

1 loadingArea = [Semaphore(0) for i in range(m)]

2 loadingArea[1].signal()

3 unloadingArea = [Semaphore(0) for i in range(m)]

4 unloadingArea[1].signal()

1 def next(i):

2 return (i + 1) % m

Car Code:

1 loadingArea[i].wait()

2 load()

3 boardQueue.signal(C)

4 allAboard.wait()

5 loadingArea[next(i)].signal()

6

7 run()

8

9 unloadingArea[i].wait()

10 unload()

11 unboardQueue.signal(C)

12 allAshore.wait()

13 unloadingArea[next(i)].signal()

Passenger Code:

1 boardQueue.wait()

2 board()

3

4 mutex.wait()

5 boarders += 1

6 if boarders == C:

7 allAboard.signal()

8 boarders = 0

9 mutex.signal()

10

11 unboardQueue.wait()

12 unboard()

24 Search-Insert-Delete

Variables:

1 insertMutex = Semaphore(1)

2 noSearcher = Semaphore(1)

3 noInserter = Semaphore(1)

4 searchSwitch = Lightswitch()

5 insertSwitch = Lightswitch()

Searcher Code:

1 searchSwitch.wait(noSearcher)

2 # critical section

3 searchSwitch.signal(noSearcher)

Inserter Code:

1 insertSwitch.wait(noInserter)

2 insertMutex.wait()

3 # critical section

4 insertMutex.signal()

5 insertSwitch.signal(noInserter)

Deleter Code:

1 noSearcher.wait()

2 noInserter.wait()

3 # critical section

4 noInserter.signal()

5 noSearcher.signal()

25 Unisex Bathroom

Variables:

1 empty = Semaphore(1)

2 maleSwitch = Lightswitch()

3 femaleSwitch = Lightswitch()

4 maleMultiplex = Semaphore(3)

5 femaleMultiplex = Semaphore(3)

Female Code:

1 femaleSwitch.lock(empty)

2 femaleMultiplex.wait()

3 # bathroom code here

4 femaleMultiplex.signal()

5 female Switch.unlock(empty)

Male Code:

1 maleSwitch.lock(empty)

2 maleMultiplex.wait()

3 # bathroom code here

4 maleMultiplex.signal()

5 male Switch.unlock(empty)

26 Modus Hall

Variables:

1 heathens = 0

2 prudes = 0

3 status = ’neutral’

4 mutex = Semaphore(1)

5 heathenTurn = Semaphore(1)

6 prudeTurn = Semaphore(1)

7 heathenQueue = Semaphore(0)

8 prudeQueue = Semaphore(0)

Solution:

1 heathenTurn.wait()

2 heathenTurn.signal()

3

4 mutex.wait()

5 heathens++

6

7 if status == ’neutral’:

8 status = ’heathens rule’

9 mutex.signal()

10 elif status == ’prudes rule’:

11 if heathens > prudes:

12 status = ’transition to heathens’

13 prudeTurn.wait()

14 mutex.signal()

15 heathenQueue.wait()

16 elif status == ’transition to heathens’:

17 mutex.signal()

18 heathenQueue.wait()

19 else

20 mutex.signal()

21

22 # cross the field

23

24 mutex.wait()

25 heathens--

26

27 if heathens == 0:

28 if status == ’transition to prudes’:

29 prudeTurn.signal()

30 if prudes:

31 prudeQueue.signal(prudes)

32 status = ’prudes rule’

33 else:

34 status = ’neutral’

35

36 if status == ’heathens rule’:

37 if prudes > heathens:

38 status = ’transition to prudes’

39 heathenTurn.wait()

40

41 mutex.signal()

27 Sushi Bar

Variables:

1 eating = waiting = 0

2 mutex = Semaphore(1)

3 block = Semaphore(0)

4 must_wait = False

Solution #1:

1 mutex.wait()

2 if must_wait:

3 waiting += 1

4 mutex.signal()

5 block.wait()

6 else:

7 eating += 1

8 must_wait = (eating == 5)

9 mutex.signal()

10

11 # eat sushi

12

13 mutex.wait()

14 eating -= 1

15 if eating == 0:

16 n = min(5, waiting)

17 waiting -= n

18 eating += n

19 must_wait = (eating == 5)

20 block.signal(n)

21 mutex.signal()

Solution #2:

1 mutex.wait()

2 if must_wait:

3 waiting += 1

4 mutex.signal()

5 block.wait() # when we resume, we have the mutex

6 waiting -= 1

7

8 eating += 1

9 must_wait = (eating == 5)

10 if waiting and not must_wait:

11 block.signal() # and pass the mutex

12 else:

13 mutex.signal()

14

15 # eat sushi

16

17 mutex.wait()

18 eating -= 1

19 if eating == 0: must_wait = False

20

21 if waiting and not must_wait:

22 block.signal() # and pass the mutex

23 else:

24 mutex.signal()

4

1 Child Care

Variables:

1 multiplex = Semaphore(0)

2 mutex = Semaphore(1)

Solution:

1 multiplex.signal(3)

2

3 # critical section

4

5 mutex.wait()

6 multiplex.wait()

7 multiplex.wait()

8 multiplex.wait()

9 mutex.signal()

2 Extended Child Care

Variables:

1 children = adults = waiting = leaving = 0

2 mutex = Semaphore(1)

3 childQueue = Semaphore(0)

4 adultQueue = Semaphore(0)

Child Code:

1 mutex.wait()

2 if children < 3 * adults:

3 children++

4 mutex.signal()

5 else:

6 waiting++

7 mutex.signal()

8 childQueue.wait()

9

10 # critical section

11

12 mutex.wait()

13 children--

14 if leaving and children = 50

8

9 if students >= 50:

10 dean = ’in the room’

11 breakup()

12 turn.wait() # lock the turnstile

13 mutex.signal()

14 clear.wait() # and get mutex from the student.

15 turn.signal() # unlock the turnstile

16

17 else: # students must be 0

18 search()

19

20 dean = ’not here’

21 mutex.signal()

Student Code:

1 mutex.wait()

2 if dean == ’in the room’:

3 mutex.signal()

4 turn.wait()

5 turn.signal()

6 mutex.wait()

7

8 students += 1

9

10 if students == 50 and dean == ’waiting’:

11 lieIn.signal() # and pass mutex to the dean

12 else:

13 mutex.signal()

14

15 party()

16

17 mutex.wait()

18 students -= 1

19

20 if students == 0 and dean == ’waiting’:

21 lieIn.signal() # and pass mutex to the dean

22 elif students == 0 and dean == ’in the room’:

23 clear.signal() # and pass mutex to the dean

24 else:

25 mutex.signal()

4 Senate Bus

Variables:

1 riders = 0

2 mutex = Semaphore(1)

3 multiplex = Semaphore(50)

4 bus = Semaphore(0)

5 allAboard = Semaphore(0)

Bus Code:

1 mutex.wait()

2 if riders > 0:

3 bus.signal() # and pass the mutex

4 allAboard.wait() # and get the mutex back

5 mutex.signal()

6

7 depart()

Riders Code:

1 multiplex.wait()

2 mutex.wait()

3 riders += 1

4 mutex.signal()

5

6 bus.wait() # and get the mutex

7 multiplex.signal()

8

9 boardBus()

10

11 riders -= 1

12 if riders == 0:

13 allAboard.signal()

14 else:

15 bus.signal() # and pass the mutex

5 Alternate Senate Bus Solution

Variables:

1 waiting = 0

2 mutex = new Semaphore(1)

3 bus = new Semaphore(0)

4 boarded = new Semaphore(0)

Bus Code:

1 mutex.wait()

2 n = min(waiting, 50)

3 for i in range(n):

4 bus.signal()

5 boarded.wait()

6

7 waiting = max(waiting-50, 0)

8 mutex.signal()

9

10 depart()

Riders Code:

1 mutex.wait()

2 waiting += 1

3 mutex.signal()

4

5 bus.wait()

6 board()

7 boarded.signal()

6 Faneuil Hall

Variables:

1 noJudge = Semaphore(1)

2 entered = 0

3 checked = 0

4 mutex = Semaphore(1)

5 confirmed = Semaphore(0)

Immigrant Code:

1 noJudge.wait()

2 enter()

3 entered++

4 noJudge.signal()

5

6 mutex.wait()

7 checkIn()

8 checked++

9

10 if judge = 1 and entered == checked:

11 allSignedIn.signal() # and pass the mutex

12 else:

13 mutex.signal()

14

15 sitDown()

16 confirmed.wait()

17

18 swear()

19 getCertificate()

20

21 noJudge.wait()

22 leave()

23 noJudge.signal()

Judge Code:

noJudge.wait()

2 mutex.wait()

3

4 enter()

5 judge = 1

6

7 if entered > checked:

8 mutex.signal()

9 allSignedIn.wait() # and get the mutex back.

10

11 confirm()

12 confirmed.signal(checked)

13 entered = checked = 0

14

15 leave()

16 judge = 0

17

18 mutex.signal()

19 noJudge.signal()

Spectator Code:

1 noJudge.wait()

2 enter()

3 noJudge.signal()

4

5 spectate()

6

7 leave()

7 Dining Hall

Variables:

1 eating = 0

2 readyToLeave = 0

3 mutex = Semaphore(1)

4 okToLeave = Semaphore(0)

Solution:

1 getFood()

2

3 mutex.wait()

4 eating++

5 if eating == 2 and readyToLeave == 1:

6 okToLeave.signal()

7 readyToLeave--

8 mutex.signal()

9

10 dine()

11

12 mutex.wait()

13 eating--

14 readyToLeave++

15

16 if eating == 1 and readyToLeave == 1:

17 mutex.signal()

18 okToLeave.wait()

19 elif eating == 0 and readyToLeave == 2:

20 okToLeave.signal()

21 readyToLeave -= 2

22 mutex.signal()

23 else:

24 readyToLeave--

25 mutex.signal()

26

27 leave()

7 User Interface Design

The idea behind the user interface is an interface that is easy and intuitive to use. As seen in this document the user interface is built of Drivers including the Main Driver and Sub Drivers. The formatting that is being applied to the user interface is the generic formatting. It will be Microsoft Windows formatting once everything is completed. There will not be a thorough examination of the user interface as that has already been covered. Instead this final statement will be about the idea of flexibility in an interface. Right now a new design mechanic is being developed for this application. It will be housed in the Dynamic Driver. This Sub Driver will be an invisible driver that will allow users to input their own Sub Drivers and Cases. Depending on what Sub Drivers or Cases a user adds will change the way the user interface looks. The only conventions that will remain the same are the sizes of the buttons on the Main Driver. Any user created Sub Driver may have its own formatting conventions. The only thing that must stay the same is that each Case that a user creates can only accept one parameter, which is a JTextArea.

Testing Design

1 Introduction

1 Unit Testing

The Unit Testing will be completed on every feature of the Main Driver, Sub Drivers, and Cases. First testing will be done on each button of the Main Driver. This will make sure that each button works and sends the user to the correct Sub Driver. Next each Sub Driver will be tested for each of its buttons and drop down menus. It will also be tested to see if the save feature works correctly. The drop down menu will be tested to make sure that it is up to date and each Case has the ability to be launched successfully. Each Sub Driver will also be tested for output issues. These output issues will be concurrency problems with output and multiple Sub Drivers open at once. The Cases need to be tested for logically correct algorithms. They will be tested and checked that the follow all logic of the original source material, “The Little Book of Semaphores” by Allen B. Downey. They will also be tested to make sure that output is synchronized and that the Sub Drivers are receiving the output correctly.

2 Subsystem Testing

The Subsystem Testing will be completed by taking the three parts of the application: Main Driver, Sub Drivers, Cases; making sure that all the features and functions work together within each of these parts. First testing will make sure that the buttons for the Main Driver work after a button is clicked and that the exit button works as expected. The next testing will be for the Sub Drivers. This testing will be more in-depth as the Sub Drivers run the Cases. All Sub Drivers will be tested for any crash bugs or output bugs while using features. The save feature of the Sub Drivers will be tested to make sure that all save boxes that are open correspond to the correct Sub Driver and that saving works as intended. For the Cases; all testing will be done the same as it is for the Unit Testing, where the integrity of the algorithm is checked. Threads will also be tested to make sure they are operating as expected, however extensive testing of the algorithms will take up a bulk of the testing done on Cases.

3 System Testing, Validate Requirements

Once all testing of the Subsystems is done, testing on the whole application will begin. How this will be tested is by running through the entire application and making sure every feature works when other features are running. Stress testing on the application will be preformed to make sure that nothing the user does can crash the application. Requirements of the user have already been validated at the time of writing the application. The application is written using the newest version of Java 6. The application will, by means of how it is programmed, use Java. The user only needs Java to run the application. The only thing that is not known is if the application will be turned into a Java applet or not. If the application is a Java applet, the user will only need Java 6, however if application is not turned into an applet then the Java SDK will be needed to run the Java command or the use of an IDE will be needed. A user may run this application on any system without problems, they will however need the OS the user needs to be a GUI powered OS, if Java Swing is not supported, it will not be able to be used. Users actual hardware will not make an impact to being able to run the application, however it will impact performance. CPU that are capable of hyperthreading and or multi-core CPU will give better and more varied results as well as faster results than single core CPU hardware.

4 Acceptance Testing

The final testing, Acceptance Testing, will test the usability and intuitiveness of the application in terms of computer science knowledge and base user knowledge. The goal of the application is to give a testing environment for computer science students to use so they can better understand the usage of semaphores in a synchronized environment. The first test will be on, “Will a user given this application know what to click to start a function.” If the answer to this is “yes” then the first test is a success, if it is “no” then changes must be made to make the application more intuitive. Next testing must be done of how well the application can be customized. “Is the documentation provided enough that a computer scientist could make changes to the application and additions in terms of Cases and Sub Drivers?” If the answer to his is “yes” then this feature of the application was a success, if it is a “no” then changes must be made to the documentation or to the application. If the user must use the User Manual or documentation to solve any problems with the application this is acceptable, however if any questions a user may have are not answered in the User Manual or documentation then changes must be made.

2 Testing

1 Testing List

Main Driver

Single Driver Button

Double Driver Button

Exit Button

Single Driver

Run Button

Drop Down List

All Cases implemented correctly and included

File Menu Button

Save Button

Save Driver being called correctly

Close Button

JTextArea

Output is correct and formatting correctly

Double Driver

Run Button

Drop Down List

All Cases implemented correctly and included

File Menu Button

Save Button

Save Driver being called correctly

Close Button

JTextArea

Output is correct and formatting correctly

Save Driver

Save Button

Make sure save button is saving to defined save directory

Make sure saving will close out of Save Driver window

Cases

Logging Thread

Check for errors in Logging Thread

Threads

Make sure threads are implemented correctly

Algorithm

Make sure algorithms used are correct and logic transferred over to Java is correct

2 Requirements Traceability

What needs to be tested overall is the ability for the application to successfully execute any algorithm a Case may present. This can be done utilizing the three tier hierarchy specified in the System Design and Speciation's documents. The three tier hierarchy makes sure that each part of the hierarchy is independent of every other part. This way a user is able to manipulate a piece of the application without the need of compatibility issues. Interactions between the hierarchies is either button presses or a uniform parameter sent, because of this the application is able to adapt to any user created content.

3 Testing Schedule

Testing on all functions of the Sub Drivers has already been finished. Testing on the Cases will start once all Cases are implemented. Each Case will get a thorough examination to determine if it conforms with the original algorithm's logic. Testing will also focus on the implementation of the Java structure and features utilized to make sure that these features are comparable to those of the algorithms original language. Once all of the Cases are tested and confirmed that their logic matches that of the algorithms, the application will undergo a full testing phase for last minute bug testing. Once this is finished the application will be ready for user usage.

4 Test Recording Procedures

All testing will be recorded on a "Case by Case" basis. This means that each Case that is tested will have its own page in a document specifying any problems encountered during testing. If no problems are found for a Case, the Case is removed from the document and the next Case in the document is then tested. The Drivers recording will be handled differently. Because the Drivers have been completely implemented and have not shown any bugs as of yet; testing can be held to a minimum. Instead, any problems that surface in the development process have already been fixed while developing the code. Any bugs or errors that do occur from the time of this document being written to release will be fixed on site while the code is being developed.

5 Hardware and Software Requirements

There are no specific hardware requirements for the application. Instead the user has been warned that results of the application will vary depending on the type of CPU utilized. If the user has a multi-core processor with hyperthreading, the user may see more varied results from algorithms than they might see had they used a single-core processor. The software required for the user to run this application is the most current version of Java 6. It is still yet to determine if this application will be a Java applet. If this application is a Java applet all the user will need is the JRE that is compatible with Java 6. If this application is not implemented as a Java applet then the user will need the most current version of the Java SDK or JDK that is compatible or on par to Java 6. They will then also need knowledge of knowing Java commands for a consol, or have an IDE capable of running Java code. Based on user accessibility and allowing for intuitive control of the application, this application would need to be a Java applet.

User Manual

1 Introduction

One thing many students in the field of Computing Science have trouble with is the subject of Threading and Synchronization. This problem includes the ideas of synchronization and protection through the use of Semaphores. To understand their use you must have an understanding of parallel computing and grasp the idea of multiple processes accessing the same data and or resources. The objective for this application is to enable a greater understanding of Semaphore use through threading. The hopes of this application are for a very easy to use application that is lightweight with a well documented and organized program files that any programmer and or user can understand the uses of Semaphores.

All students need help from time to time, my application will do just that. It will help students who need a supplement or a visual to see just how threading and Semaphores work. Semaphores are one of the more advanced topics in the field of Computing Science, to have a reliable source that can help a student better understand Semaphores and its use in threads could set some students minds at ease; even help other students achieve a higher understanding of the topic. Even students who don't necessarily need to use this application as a learning tool in the sense of seeing how Semaphores work can use this application to test out different common and uncommon cases of Semaphore solutions. The application will come with a finite number of Semaphore solutions, all of which have cases with and without semaphores to demonstrate the difference between a program being protected and unprotected. If a student wants to see just what the effects an unprotected program will have, that student can with my application. A student may also write their own cases or even other "drivers" to be used with the application. If an example is not there for a student to use, a student may add this into the application, using the guidelines I create and just add the file to a Java package.

The system includes a Main Driver from which all Sub Drivers can be launched from. The Sub Drivers that are launched from the Main Driver are the Single Driver and the Double Driver. Both drivers are used by the user to both launch and visualize a Case and the algorithm the Case contains. Both the Single Driver and Double Driver also can call the Save Driver. The Save Driver has the ability to save the output that is displayed on the output window of both the Single Driver and Double Driver. A user will also have the ability to edit or add both Sub Drivers and Cases. All of these components come together for a system that can both engage and educate anyone with the ability and drive to learn the aspect of semaphores and threading in programming.

2 Introductory Manual

1 How to Use the System

1 Main Driver

The Main Driver is the first component that you will see when starting up the application. This window is 200 pixels wide by 350 pixels long. The Main Driver is composed of three buttons currently. The three buttons are the Single button, Double button, and Exit button. Each button is 80 pixels wide by 30 pixels long. The Main Driver uses the default layout, meaning that it uses a uniform "Java" look to it. You may navigate to the two Sub Drivers by clicking their corresponding buttons. Launching a Sub Driver does not stop the Main Driver and you may launch multiple Sub Drivers if you please. There is also an exit button which can be clicked. Upon clicking the exit button the application will terminate, any and all work will not be saved upon termination and all Sub Driver windows will also close upon termination.

- Single Driver Button

Clicking on this will launch the Single Driver

- Main Driver Button

Clicking on this will launch the Double Driver

- Exit Button

Clicking on this will terminate all processes associated with the application. WARNING: All work will not be saved and all processes will be terminated!

2 Single Driver

The Single Driver is the one of two Sub Drivers that you may launch upon clicking the corresponding button from the Main Driver. This Sub Driver is used as a launching point for both a visualization and an executable for all Cases housed within the application. The window is 500 pixels wide by 600 pixels long. It consists of a JTextArea with a JScrollPane of 400 pixels wide by 400 pixels long, a JComboBox of 150 pixels wide by 20 pixels long, and a Run button of 80 pixels wide by 30 pixels long. The Single Driver also includes a menu bar with the drop down menu File that consists of Save and Close, all of which are 20 pixels long. The Single Driver is used by selecting a Case to execute with the drop down box below the output window. Once you have selected an output you must then press Run. When pressing Run the Single Driver will then execute the Case. You may save the output of the output window by selecting File then Save.

- Drop down box

Gives ability to select which Case will be executed. Drop down box is always selected on first item if no item is selected.

- Run button

When clicked Single Driver will execute selected Case. WARNING: User has the ability to press Run multiple times without constraint. This can lead to unexpected output as multiple Cases will attempt to output to the same output window.

- File menu

Holds the Save and Close commands. Save will execute the Save Driver. Close will currently do nothing.

3 Double Driver

Double Driver is the second Sub Driver launched from the Main Driver. The window is 500 pixels wide by 600 pixels long. It consists of two JTextArea with a JScrollPane of 200 pixels wide by 400 pixels long, two JComboBox of 150 pixels wide by 20 pixels long, and a Run button of 80 pixels wide by 30 pixels long. The Double Driver also includes a menu bar with the drop down menu File that consists of Save and Close, all of which are 20 pixels long. What the user cannot see is the switch used to determine the user selection on the combo box as well as the list used to populate the combo boxes. The Double Driver also utilizes threads to achieve a concurrent execution of two Cases instead of one. The Double Driver is used by selecting a Case to execute with both drop down boxes below the output windows. Each drop down box corresponds to the output window it is below. Once you have selected the Cases you must then press Run. When pressing Run the Single Driver will then execute the Case. You may save the output of the output windows by selecting File then Save.

- Drop down box

Gives ability to select which Case will be executed. Drop down box is always selected on first item if no item is selected.

- Run button

When clicked Single Driver will execute selected Cases. WARNING: User has the ability to press Run multiple times without constraint. This can lead to unexpected output as multiple Cases will attempt to output to the same output window.

- File menu

Holds the Save and Close commands. Save will execute the Save Driver. Close will currently do nothing.

2

1 Save Driver

The Save Driver is launched from either the Single Driver or Double Driver. It functions as a save feature for the output displayed in either the Single Driver output window or Double Driver output windows. . The window of the Save Driver is 450 pixels wide by 200 pixels long. It consists of three objects. The first is the JButton, "Save", of which is 80 pixels wide by 30 pixels long. The second is a JLabel which includes the words "Enter in file name: ." The third is the JTextField which is 120 pixels wide by 10 pixels long. When the Save Driver window appears you will be able to enter in a name for the file you would like to save to. This file can be named anything you want. You do need to add an extension to the file. If you do not you must then add it afterwards. Once you enter in the file name you may press the Save button. Upon pressing the Save button the window will close and save the file. The file is saved to the same directory that the executable for the application is found, unless running source code which the output can be found in the home directory for the application, this is the directory that is the name for the application and is where all other directories are stored for the application. This assumes that the user is using Eclipse. I cannot vouch for any other IDE and do not know where they may send output save.

- Save name field

Where user enters in name of file to save. WARNING: User will have to enter in own extension for file(.txt, .doc, .odt).

- Save button

Button for user to click after entering in save file name. Once user clicks button Save Driver window will close.

2 Cases

Cases are tests that hold all the algorithm information and produce the output a user sees in the Single Driver and Double Driver. Cases are launched by the Single Driver and Double Driver. A Case may ask a user for additional information when they Run one from the Single Driver or Double Driver. This will be in the form of an extra window that will launch. This window contains a few text fields that a user can type into and a Run button. A user will receive an error message if input does not follow guidelines of algorithm and will have to input information again before the Case can be executed. The case has no dimensions as each window a Case can produce may contain different amounts of information. A Case does not have to produce this window and so a user may not be prompted for extra information at all.

3  Information on Help System

There is no real help system in the application. Most errors are due to user created content or user input while using a specific Case that prompts user for input. Most input is screened before running, but a valid input may be an integer which could be as simple as 5000. This 5000 would then start 5000 threads, or could cause all threads to flow through a loop 5000 times, causing the application to appear frozen when in actuality it is just attempting to create 5000 threads which can take some time or have the application flow through a loop.

1 How to Build Your Own Case and Driver

This guide is just some quick guidelines on how you should build a Case or Driver. The easiest way to build a Case is to look at the other Case examples in the source code. The same can be said for Sub Drivers.

- All Case that I have written only accept one JTextArea. This JTextArea is accepted into the constructor of the Case as a parameter.

- If you write your own Case remember to add it to the String called "cases". Remember to add the declaration and instantiation of the corresponding Case Object in the Switch. Remember that the Switch number should correspond to the location of the Case name in the String "cases".

- If you write your own Case it does not need to follow the guidelines of one JTextArea however remember that you must correctly send all parameters. If you build a special Case remember it is your responsibility to correct the issue of parameters sent in the Sub Drivers.

- If you write your own Sub Driver remember that all Cases that I wrote only accept one JTextArea so if they are passed other parameters besides a JTextArea I cannot guarantee success unless these Case files are modified.

- If you build another Sub Driver, remember to add it to the Main Driver so you can execute it. Or if it is a new feature for a Sub Driver to use, remember to add it to other Sub Drivers.

- If in a patch a "Dynamic Building System" is added. All information posted in this section will become irrelevant. A new guide will be released with this section replaced with a section on the "Dynamic Building System."

3 System Reference Manual

1 List of Services

Case - Class that contains the Algorithm to be executed.

Double Driver - A double output test. May run two Cases at a time.

Main Driver - Used to launch Single Driver and Double Driver. Also used to terminate application.

Save Driver - Saves the output of both Single Driver and Double Driver. User enters in file name to save output to. User must include the extension of the file when naming it.

Single Driver - Runs a single Case with one output window.

2 Error Recovery

This application does include error catching to an extent. If by some circumstance a thread is called twice there may be an error. If there is an error the best course of action is to close out the Sub Driver window. You may keep the Main Driver window open as the Sub Drivers should not affect the Main Driver. Problems of freezing may occur on slower systems when trying to run algorithms where hundreds or more threads are created. The application will appear to not produce any output and mimic freezing. The application is usually not frozen, it is only creating and running each thread. To run multiple threads at once, a loop must be used to start each thread. If there are hundreds or even thousands of threads to start; it may take time to start.

3 Installation Information

1 Executable Jar File

1. Download executable jar file

2. Double click on executable jar file to run application

- You must have the Java SE2 environment to run this application. The SE2 environment includes Java 6th edition in it.

2 Source Code

1. Download source code files

2. Compile and run source code files in your favorite IDE

- This application has been built in the Eclipse IDE using JDK 6

Appendix

1 Cases

1 Barbershop.java

package cases;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

public class Barbershop extends JFrame {

/**

*

*/

private static final long serialVersionUID = 1L;

int customers = 0;

int n; /* needed to be added: number of chairs */

Semaphore mutex = new Semaphore(1);

Semaphore customer = new Semaphore(0);

Semaphore barber = new Semaphore(0);

int barberamount = 1;

int customeramount;

int threadcount;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Barbershop(final JTextArea a) {

final JTextField inputcustomer = new JTextField();

final JTextField inputchairs = new JTextField();

JButton runbutton = new JButton("Run");

setSize(200, 200);

setTitle("Barbershop");

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width / 2 - getWidth() / 2, size.height / 2

- getHeight() / 2);

final JPanel panel = new JPanel();

getContentPane().add(panel);

panel.setLayout(null);

JLabel label = new JLabel("Customer amount: ");

label.setBounds(5, 10, 150, 20);

JLabel label2 = new JLabel("Chair amount: ");

label2.setBounds(5, 40, 150, 20);

inputcustomer.setBounds(115, 10, 50, 20);

inputchairs.setBounds(115, 40, 50, 20);

runbutton.setBounds(50, 100, 80, 30);

runbutton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

boolean check = setvariable(inputcustomer.getText(),

inputchairs.getText());

if (check) {

execute(a);

} else {

JOptionPane.showMessageDialog(panel,

"Error: Incorrect input!");

}

}

});

panel.add(label);

panel.add(label2);

panel.add(inputcustomer);

panel.add(inputchairs);

panel.add(runbutton);

this.setVisible(true);

}

public boolean setvariable(String a, String b) {

try {

customeramount = Integer.parseInt(a);

n = Integer.parseInt(b);

} catch (NumberFormatException nfe) {

return false;

}

threadcount = barberamount + customeramount;

System.out.println(customeramount + " " + n);

return true;

}

public void execute(final JTextArea a) {

this.setVisible(false);

/* customer thread creation */

ArrayList customers = new ArrayList();

for (int i = 0; i < customeramount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

barbershopcustomer();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

customers.add(t1);

}

/* barber thread creation */

final Thread barber = new Thread(new Runnable() {

public void run() {

try {

barbershopbarber();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

barber.start();

for (int i = 0; i < threadcount - 1; i++) {

customers.get(i).start();

}

}

public void barbershopcustomer() throws InterruptedException {

mutex.acquire();

if (customers == n + 1) {

mutex.release();

logqueue.add("customer balk(); \n");

return;

}

customers = customers + 1;

mutex.release();

customer.release();

barber.acquire();

logqueue.add("customer getHairCut(); \n");

mutex.acquire();

customers = customers + 1;

mutex.release();

logqueue.add("END");

}

public void barbershopbarber() throws InterruptedException {

int i = 0;

while (i < threadcount - 1) {

customer.acquire();

barber.release();

logqueue.add("barber cutHair(); \n");

}

logqueue.add("Barber is done! \n");

logqueue.add("END");

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

2 Barrier.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Barrier {

final Semaphore aArrived = new Semaphore(0);

final Semaphore bArrived = new Semaphore(0);

final Semaphore mutex = new Semaphore(1);

final Semaphore barrier = new Semaphore(0);

int count = 0;

int n = 4; // number of threads

int threadcount = n;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Barrier(final JTextArea a) {

/* Threadgroup1 creation */

ArrayList threadgroup1 = new ArrayList();

for (int i = 0; i < (threadcount / 2); i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

rendezvous1();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

threadgroup1.add(t1);

}

/* Threadgroup2 creation */

ArrayList threadgroup2 = new ArrayList();

for (int i = 0; i < (threadcount / 2); i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

rendezvous2();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

threadgroup2.add(t1);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for(int i = 0; i< (threadcount / 2); i++){

threadgroup1.get(i).start();

threadgroup2.get(i).start();

}

}

public void rendezvous1() throws InterruptedException {

logqueue.add("Statement a1 \n");

aArrived.release();

bArrived.acquire();

logqueue.add("Statement a2 \n");

barrierwait();

}

public void rendezvous2() throws InterruptedException {

logqueue.add("Statement b1 \n");

bArrived.release();

aArrived.acquire();

logqueue.add("Statement b2 \n");

barrierwait();

}

public void barrierwait() throws InterruptedException {

mutex.acquire();

count = count + 1;

mutex.release();

if (count == threadcount) {

logqueue.add("Releasing barrier \n");

barrier.release();

}

logqueue.add("At barrier \n");

barrier.acquire();

barrier.release();

logqueue.add("At Critical Section \n");

logqueue.add("END");

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

3 Barrier_Deadlock.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Barrier_Deadlock {

final Semaphore aArrived = new Semaphore(0);

final Semaphore bArrived = new Semaphore(0);

final Semaphore mutex = new Semaphore(1);

final Semaphore barrier = new Semaphore(0);

int count = 0;

int n = 4; // number of threads

int threadcount = n;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Barrier_Deadlock(final JTextArea a) {

/* Threadgroup1 creation */

ArrayList threadgroup1 = new ArrayList();

for (int i = 0; i < (threadcount / 2); i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

rendezvous1();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

threadgroup1.add(t1);

}

/* Threadgroup2 creation */

ArrayList threadgroup2 = new ArrayList();

for (int i = 0; i < (threadcount / 2); i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

rendezvous2();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

threadgroup2.add(t1);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for(int i = 0; i< (threadcount / 2); i++){

threadgroup1.get(i).start();

threadgroup2.get(i).start();

}

}

public void rendezvous1() throws InterruptedException {

logqueue.add("Statement a1 \n");

aArrived.release();

bArrived.acquire();

logqueue.add("Statement a2 \n");

barrierwait();

}

public void rendezvous2() throws InterruptedException {

logqueue.add("Statement b1 \n");

bArrived.release();

aArrived.acquire();

logqueue.add("Statement b2 \n");

barrierwait();

}

public void barrierwait() throws InterruptedException {

mutex.acquire();

count = count + 1;

mutex.release();

if (count == threadcount) {

logqueue.add("Releasing barrier \n");

barrier.release();

}

logqueue.add("At barrier \n");

barrier.acquire();

logqueue.add("At Critical Section \n");

logqueue.add("END");

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

4 Barrier_Deadlock2.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Barrier_Deadlock2 {

final Semaphore aArrived = new Semaphore(0);

final Semaphore bArrived = new Semaphore(0);

final Semaphore mutex = new Semaphore(1);

final Semaphore barrier = new Semaphore(0);

int count = 0;

int n = 4; // number of threads

int threadcount = n;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Barrier_Deadlock2(final JTextArea a) {

/* Threadgroup1 creation */

ArrayList threadgroup1 = new ArrayList();

for (int i = 0; i < (threadcount / 2); i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

rendezvous1();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

threadgroup1.add(t1);

}

/* Threadgroup2 creation */

ArrayList threadgroup2 = new ArrayList();

for (int i = 0; i < (threadcount / 2); i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

rendezvous2();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

threadgroup2.add(t1);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for(int i = 0; i< (threadcount / 2); i++){

threadgroup1.get(i).start();

threadgroup2.get(i).start();

}

}

public void rendezvous1() throws InterruptedException {

logqueue.add("Statement a1 \n");

aArrived.release();

bArrived.acquire();

logqueue.add("Statement a2 \n");

barrierwait();

}

public void rendezvous2() throws InterruptedException {

logqueue.add("Statement b1 \n");

bArrived.release();

aArrived.acquire();

logqueue.add("Statement b2 \n");

barrierwait();

}

public void barrierwait() throws InterruptedException {

mutex.acquire();

logqueue.add("Mutex acquired \n");

count = count + 1;

if (count == n) {

logqueue.add("Barrier released \n");

barrier.release();

}

logqueue.add("At barrier \n");

barrier.acquire();

barrier.release();

logqueue.add("Out of barrier \n");

mutex.release();

logqueue.add("Mutex released \n");

logqueue.add("END");

/* critical point */

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

5 Building_H2O.java

package cases;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.ArrayList;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.Semaphore;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

public class Building_H2O extends JFrame {

private static final long serialVersionUID = 1L;

Semaphore mutex = new Semaphore(1);

int oxygen = 0;

int hydrogen = 0;

CyclicBarrier barrier = new CyclicBarrier(3);

Semaphore oxyQueue = new Semaphore(0);

Semaphore hydroQueue = new Semaphore(0);

int oxygenamount;

int hydrogenamount;

int threadcount;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Building_H2O(final JTextArea a) {

final JTextField oxyamount = new JTextField();

JButton runbutton = new JButton("Run");

setSize(225, 200);

setTitle("Building H2O");

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width / 2 - getWidth() / 2, size.height / 2

- getHeight() / 2);

final JPanel panel = new JPanel();

getContentPane().add(panel);

panel.setLayout(null);

JLabel label = new JLabel("Amount of Oxygen: ");

JLabel label2 = new JLabel("Hydrogen will be calculated ");

JLabel label3 = new JLabel("from amount of Oxygen");

label.setBounds(5, 10, 150, 20);

label2.setBounds(5,20,200,80);

label3.setBounds(5,40,200,80);

oxyamount.setBounds(115, 10, 50, 20);

runbutton.setBounds(50, 100, 80, 30);

runbutton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

boolean check = setvariable(oxyamount.getText());

if (check) {

execute(a);

} else {

JOptionPane.showMessageDialog(panel,

"Error: Incorrect input!");

}

}

});

panel.add(label);

panel.add(label2);

panel.add(label3);

panel.add(oxyamount);

panel.add(runbutton);

this.setVisible(true);

}

public void execute(final JTextArea a) {

/* oxygen thread creation */

ArrayList oxygen = new ArrayList();

for (int i = 0; i < oxygenamount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

Oxygen();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (BrokenBarrierException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

oxygen.add(t1);

}

/* oxygen thread creation */

ArrayList hydrogen = new ArrayList();

for (int i = 0; i < hydrogenamount; i++) {

final Thread t2 = new Thread(new Runnable() {

public void run() {

try {

Hydrogen();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (BrokenBarrierException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

hydrogen.add(t2);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for (int k = 0; k < hydrogenamount; k++) {

hydrogen.get(k).start();

}

for (int j = 0; j < oxygenamount; j++) {

oxygen.get(j).start();

}

}

public boolean setvariable(String a) {

try {

oxygenamount = Integer.parseInt(a);

} catch (NumberFormatException nfe) {

return false;

}

hydrogenamount = oxygenamount * 2;

threadcount = oxygenamount + hydrogenamount;

return true;

}

public void Oxygen() throws InterruptedException, BrokenBarrierException {

mutex.acquire();

oxygen = oxygen + 1;

if (hydrogen >= 2) {

hydroQueue.release(2);

hydrogen = hydrogen - 2;

oxyQueue.release();

oxygen = oxygen - 1;

}

else {

mutex.release();

}

oxyQueue.acquire();

logqueue.add("Oxygen Bond(); \n");

logqueue.add("END");

barrier.await();

mutex.release();

}

public void Hydrogen() throws InterruptedException, BrokenBarrierException {

mutex.acquire();

hydrogen = hydrogen + 1;

if (hydrogen >= 2 && oxygen >= 1) {

hydroQueue.release(2);

hydrogen = hydrogen - 2;

oxyQueue.release();

oxygen = oxygen - 1;

}

else {

mutex.release();

}

hydroQueue.acquire();

logqueue.add("Hydrogen Bond(); \n");

logqueue.add("END");

barrier.await();

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

6 Dining_Philosophers.java

package cases;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

/* uses 5 threads */

public class Dining_Philosophers extends JFrame{

private static final long serialVersionUID = 1L;

Semaphore fork[] = new Semaphore[5];

Semaphore footman = new Semaphore(4);

int threadcount = 5;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

int philosophernumber = -1;

int willeat ; /* A philosopher will eat # times */

public Dining_Philosophers(final JTextArea a) {

final JTextField philosopherwilleat = new JTextField();

JButton runbutton = new JButton("Run");

setSize(200, 200);

setTitle("Dining Philosophers");

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width / 2 - getWidth() / 2, size.height / 2

- getHeight() / 2);

final JPanel panel = new JPanel();

getContentPane().add(panel);

panel.setLayout(null);

JLabel label = new JLabel("Philosopher eats: ");

label.setBounds(5, 10, 150, 20);

philosopherwilleat.setBounds(115, 10, 50, 20);

runbutton.setBounds(50, 100, 80, 30);

runbutton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

boolean check = setvariable(philosopherwilleat.getText());

if (check) {

execute(a);

} else {

JOptionPane.showMessageDialog(panel,

"Error: Incorrect input!");

}

}

});

panel.add(label);

panel.add(philosopherwilleat);

panel.add(runbutton);

this.setVisible(true);

}

public boolean setvariable(String a) {

try {

willeat = Integer.parseInt(a);

} catch (NumberFormatException nfe) {

return false;

}

return true;

}

public void execute(final JTextArea a){

this.setVisible(false);

for (int i = 0; i < 5; i++) {

fork[i] = new Semaphore(1);

}

/* philosopher thread creation */

ArrayList philosophers = new ArrayList();

for (int i = 0; i < threadcount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

get_forks(getphilosophernumber());

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

philosophers.add(t1);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for (int j = 0; j < threadcount; j++) {

philosophers.get(j).start();

}

}

public int left(int i) {

return i;

}

public int right(int i) {

return (i + 1) % 5;

}

public void get_forks(int i) throws InterruptedException {

for (int k = 0; k < willeat; k++) {

footman.acquire();

fork[right(i)].acquire();

fork[left(i)].acquire();

logqueue.add("Philosopher " + i + " getting chop sticks" + left(i)

+ " " + right(i) + "\n");

logqueue.add("Philosopher "+i+" is eating \n");

Thread.sleep(1000);

put_forks(i);

}

logqueue.add("END");

}

public void put_forks(int i) throws InterruptedException {

logqueue.add("Philosopher " + i + " putting down chop sticks "

+ left(i) + " " + right(i) + "\n");

fork[right(i)].release();

fork[left(i)].release();

footman.release();

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

public synchronized int getphilosophernumber() {

philosophernumber = philosophernumber + 1;

return philosophernumber;

}

}

7 Dining_Savages.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Dining_Savages {

int servings = 0;

int M = 5; /* needed to be added */

int full = 2; /* how many times a savage will eat before full */

Semaphore mutex = new Semaphore(1);

Semaphore emptyPot = new Semaphore(0);

Semaphore fullPot = new Semaphore(0);

int threadcount = 21;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Dining_Savages(final JTextArea a) {

ArrayList savages = new ArrayList();

for (int i = 0; i < threadcount - 1; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

savages();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

savages.add(t1);

}

final Thread cook = new Thread(new Runnable() {

public void run() {

try {

cook();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

cook.start();

for (int j = 0; j < threadcount - 1; j++) {

savages.get(j).start();

}

}

public void cook() throws InterruptedException {

int exit = 0;

while (exit < ((threadcount - 1) * full) / 5) {

emptyPot.acquire();

logqueue.add("Cook putServingsInPot(M) \n");

fullPot.release();

exit = exit + 1;

}

logqueue.add("Cook is done \n");

logqueue.add("END");

}

public void savages() throws InterruptedException {

int exit = 0;

while (exit < full) {

mutex.acquire();

if (servings == 0) {

emptyPot.release();

fullPot.acquire();

servings = M;

}

servings = servings - 1;

logqueue.add("Savage getServingFromPot(); \n");

mutex.release();

logqueue.add("Savage eat(); \n");

exit = exit + 1;

}

logqueue.add("END");

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

8 Exclusive_Queue.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Exclusive_Queue {

int leaders, followers = 0;

Semaphore mutex = new Semaphore(1);

Semaphore leaderQueue = new Semaphore(0);

Semaphore followerQueue = new Semaphore(0);

Semaphore rendezvous = new Semaphore(0);

int threadcount = 10;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Exclusive_Queue(final JTextArea a) {

/* leaders thread creation */

ArrayList leader = new ArrayList();

for (int i = 0; i < threadcount / 2; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

leaders();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

leader.add(t1);

}

/* followers thread creation */

ArrayList follower = new ArrayList();

for (int i = 0; i < threadcount / 2; i++) {

final Thread t2 = new Thread(new Runnable() {

public void run() {

try {

followers();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

follower.add(t2);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for (int i = 0; i < threadcount / 2; i++) {

leader.get(i).start();

follower.get(i).start();

}

}

public void leaders() throws InterruptedException {

mutex.acquire();

if (followers > 0) {

followers = followers - 1;

followerQueue.release();

} else {

leaders = leaders + 1;

mutex.release();

leaderQueue.acquire();

}

logqueue.add("leader dance(); \n");

logqueue.add("END");

rendezvous.acquire();

mutex.release();

}

public void followers() throws InterruptedException {

mutex.acquire();

if (leaders > 0) {

leaders = leaders - 1;

leaderQueue.release();

} else {

followers = followers + 1;

mutex.release();

followerQueue.acquire();

}

logqueue.add("follower dance(); \n");

logqueue.add("END");

rendezvous.release();

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

9 Modus_Hall.java

/*

* not fully implemented yet

*/

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Modus_Hall {

int heathens = 0;

int prudes = 0;

String status = "neutral";

Semaphore mutex = new Semaphore(1);

Semaphore heathenTurn = new Semaphore(1);

Semaphore prudeTurn = new Semaphore(1);

Semaphore heathenQueue = new Semaphore(0);

Semaphore prudeQueue = new Semaphore(0);

int heathensamount = 20;

int prudesamount = 20;

int threadcount = heathensamount + prudesamount;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Modus_Hall(final JTextArea a){

/* Heathen thread creation */

ArrayList heathen = new ArrayList();

for (int i = 0; i < heathensamount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

heathen();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

heathen.add(t1);

}

/* Prude thread creation */

ArrayList prude = new ArrayList();

for (int i = 0; i < prudesamount; i++) {

final Thread t2 = new Thread(new Runnable() {

public void run() {

}

});

prude.add(t2);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

}

public void heathen() throws InterruptedException {

heathenTurn.acquire();

heathenTurn.release();

mutex.acquire();

heathens = heathens + 1;

if(status.equals("neutral")){

status = "heathens rule";

mutex.release();

}

else if (status.equals("prudes rule")){

if(heathens > prudes){

status = "transition to heathens";

prudeTurn.acquire();

}

mutex.release();

heathenQueue.acquire();

}

else if (status.equals("transition to heathens")){

mutex.release();

heathenQueue.acquire();

}

else{

mutex.release();

}

/* cross the field */

mutex.acquire();

heathens = heathens - 1;

if(heathens == 0){

if(status.equals("transition to prudes")){

prudeTurn.release();

}

if (status.equals("prudes rule")){

prudeQueue.release(prudes);

status = "prudes rule";

}

else{

status = "neutral";

}

}

if(status.equals("heathens rule")){

if(prudes > heathens){

status = "transition to prudes";

heathenTurn.acquire();

}

}

mutex.release();

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

10 Multicar_Roller_Coaster.java

package cases;

/* This classes logic is unsound as there is a

* discrepancy as to how int i should be treated.

* Should each thread have an int i, or should it

* be global.

* Each car gets its own i call j, it takes the value i, then

* increments it, at any one time there should only be m

* cars, if more cars(threads) are implemented the algorithm

* will not work.

*/

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Multicar_Roller_Coaster {

Semaphore mutex = new Semaphore(1);

Semaphore mutex2 = new Semaphore(1);

Semaphore mutexcarnumber = new Semaphore(1);

int boarders = 0;

int unboarders = 0;

int C = 2; /* c = number of spots in a car */

int m = 6; /* m = number of cars per roller coaster */

int i = 1;

Semaphore boardQueue = new Semaphore(0);

Semaphore unboardQueue = new Semaphore(0);

Semaphore allAboard = new Semaphore(0);

Semaphore allAshore = new Semaphore(0);

Semaphore loadingArea[] = new Semaphore[m + 1];

Semaphore unloadingArea[] = new Semaphore[m + 1];

int caramount = 10;

int passengeramount = caramount * C;

int threadcount = caramount + passengeramount;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Multicar_Roller_Coaster(final JTextArea a) {

for (int k = 1; k = 2) {

serfQueue.release(2);

hackerQueue.release(2);

hackers = hackers - 2;

serfs = 0;

isCaptain = true;

} else {

mutex.release(); /* captain keeps the mutex */

}

serfQueue.acquire();

logqueue.add("Serf board(); \n");

barrier.await();

if (isCaptain) {

logqueue.add("Serf Captain rowBoat(); \n");

mutex.release(); /* captain releases the mutex */

}

logqueue.add("END");

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

22 Roller_Coaster.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Roller_Coaster {

Semaphore mutex = new Semaphore(1);

Semaphore mutex2 = new Semaphore(1);

int boarders = 0;

int unboarders = 0;

int C = 2; /* c = number of spots in a roller coaster */

Semaphore boardQueue = new Semaphore(0);

Semaphore unboardQueue = new Semaphore(0);

Semaphore allAboard = new Semaphore(0);

Semaphore allAshore = new Semaphore(0);

int caramount = 10;

int passengeramount = caramount * C;

int threadcount = caramount + passengeramount;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Roller_Coaster(final JTextArea a) {

/* car thread creation */

ArrayList car = new ArrayList();

for (int i = 0; i < caramount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

car();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

car.add(t1);

}

/* passenger thread creation */

ArrayList passenger = new ArrayList();

for (int i = 0; i < passengeramount; i++) {

final Thread t2 = new Thread(new Runnable() {

public void run() {

try {

passenger();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

passenger.add(t2);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for (int k = 0; k < caramount; k++) {

car.get(k).start();

}

for (int j = 0; j < passengeramount; j++) {

passenger.get(j).start();

}

}

public void car() throws InterruptedException {

logqueue.add("Car load(); \n");

boardQueue.release(C);

allAboard.acquire();

logqueue.add("Car run(); \n");

logqueue.add("Car unload(); \n");

logqueue.add("END");

unboardQueue.release(C);

allAshore.acquire();

}

public void passenger() throws InterruptedException {

boardQueue.acquire();

logqueue.add("Passenger board(); \n");

mutex.acquire();

boarders = boarders + 1;

if (boarders == C) {

allAboard.release();

boarders = 0;

}

mutex.release();

unboardQueue.acquire();

logqueue.add("Passenger unboard(); \n");

logqueue.add("END");

mutex2.acquire();

unboarders = unboarders + 1;

if (unboarders == C) {

allAshore.release();

unboarders = 0;

}

mutex2.release();

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

23 Sushi_Bar.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

public class Sushi_Bar {

int eating, waiting = 0;

Semaphore mutex = new Semaphore(1);

Semaphore block = new Semaphore(0);

Boolean must_wait = false;

int threadcount = 20;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

public Sushi_Bar(final JTextArea a) {

execute(a);

}

public void execute(final JTextArea a){

/* Patron thread creation */

ArrayList patron = new ArrayList();

for (int i = 0; i < threadcount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

sushi();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

patron.add(t1);

for(i = 0; i < threadcount; i++){

patron.get(i).start();

}

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for (int i = 0; i < threadcount; i++) {

patron.get(i).start();

}

}

public void sushi() throws InterruptedException {

mutex.acquire();

if (must_wait) {

waiting = waiting + 1;

mutex.release();

block.acquire();

} else {

eating = eating + 1;

must_wait = (eating == 5);

mutex.release();

}

logqueue.add("Patron eat sushi \n");

logqueue.add("END");

mutex.acquire();

eating = eating - 1;

if (eating == 0) {

int n = Math.min(5, waiting);

waiting = waiting - n;

eating = eating - n;

must_wait = (eating == 5);

block.release(n);

}

mutex.release();

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

}

24 Tanenbaums_Solution.java

package cases;

import java.util.ArrayList;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.Semaphore;

import javax.swing.JTextArea;

/* uses 5 threads */

public class Tanenbaums_Solution {

public String state[] = { "thinking", "thinking", "thinking", "thinking",

"thinking" };

Semaphore mutex = new Semaphore(1);

int threadcount = 5;

ConcurrentLinkedQueue logqueue = new ConcurrentLinkedQueue();

int philosophernumber = -1;

Semaphore[] sem = new Semaphore[5];

public Tanenbaums_Solution(final JTextArea a) {

for (int i = 0; i < 5; i++) {

sem[i] = new Semaphore(0);

}

/* philosopher thread creation */

ArrayList philosophers = new ArrayList();

for (int i = 0; i < threadcount; i++) {

final Thread t1 = new Thread(new Runnable() {

public void run() {

try {

int personalnumber = get_fork(getphilosophernumber());

put_fork(personalnumber);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

philosophers.add(t1);

}

/* Logging Thread */

final Thread Log = new Thread(new Runnable() {

public void run() {

try {

logger(a);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Log.start();

for (int j = 0; j < threadcount; j++) {

philosophers.get(j).start();

}

}

public int left(int i) {

return i;

}

public int right(int i) {

return (i + 1) % 5;

}

public int get_fork(int i) throws InterruptedException {

mutex.acquire();

state[i] = "hungry";

test(i);

mutex.release();

sem[i].acquire();

logqueue.add("Philosopher " + i + " picked up chop stick " + left(i)

+ " " + right(i) + "\n");

logqueue.add("Philosopher " + i + " is eating \n");

return i;

}

public void put_fork(int i) throws InterruptedException {

mutex.acquire();

state[i] = "thinking";

test(right(i));

test(left(i));

logqueue.add("Philosopher " + i + " placed down chop stick " + left(i)

+ " " + right(i) + "\n");

logqueue.add("END");

mutex.release();

}

public void test(int i) {

if (state[i].equals("hungry") && !(state[left(i)].equals("eating"))

&& !(state[right(i)].equals("eating"))) {

state[i] = "eating";

sem[i].release();

}

}

public void logger(JTextArea area) throws InterruptedException {

int endvalue = 0;

String output;

while (endvalue != threadcount) {

if (!logqueue.isEmpty()) {

output = (String) logqueue.poll();

if (output.equals("END")) {

endvalue++;

} else {

area.append(output);

}

}

Thread.sleep(50);

}

}

public synchronized int getphilosophernumber() {

philosophernumber = philosophernumber + 1;

return philosophernumber;

}

}

25 The_Santa_Claus.java

package cases;

import java.util.concurrent.Semaphore;

public class The_Santa_Claus {

int elves = 0;

int reindeer = 0;

Semaphore santaSem = new Semaphore(0);

Semaphore reindeerSem = new Semaphore(0);

Semaphore elfTex = new Semaphore(1);

Semaphore mutex = new Semaphore(1);

public void Santa() throws InterruptedException{

santaSem.acquire();

mutex.acquire();

if(reindeer == 9){

/* prepareSleigh(); */

reindeerSem.release(9);

}

else if (elves == 3){

/* helpElves() */

}

mutex.release();

}

public void reindeer() throws InterruptedException{

mutex.acquire();

reindeer = reindeer + 1;

if(reindeer == 9){

santaSem.release();

}

mutex.release();

reindeerSem.acquire();

/* getHitched(); */

}

public void elves() throws InterruptedException {

elfTex.acquire();

mutex.acquire();

elves = elves + 1;

if (elves == 3) {

santaSem.release();

}

else {

elfTex.release();

}

mutex.release();

/* getHelp(); */

mutex.acquire();

elves = elves - 1;

if (elves == 0) {

elfTex.release();

}

mutex.release();

}

}

2 Drivers

1 DoubleDriver.java

package drivers;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ItemEvent;

import java.awt.event.ItemListener;

import javax.swing.JButton;

import javax.swing.JComboBox;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import cases.*;

public class DoubleDriver extends JFrame{

final String[] cases = {"Barbershop", "Barrier", "Barrier Deadlock",

"Barrier Deadlock2", "Building H2O", "Dining Philosophers",

"Dining Savages", "Exclusive Queue", "Multicar Roller Coaster",

"Multiplex", "Multiplex no Semaphore", "Multiplex Synchronized",

"Mutex", "No Starve Mutex", "Producer Consumer", "Queue",

"Reader Writer", "Rendezvous", "Reusable Barrier",

"River Crossing", "Roller Coaster", "Sushi Bar",

"Tenenbaums Solution"};

private static final long serialVersionUID = 1L;

int index = 0;

int index2 = 0;

SaveDriver save = new SaveDriver();

public DoubleDriver(){

setSize(500, 600);

setTitle("Single Threading Test");

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width/2 - getWidth()/2,

size.height/2 - getHeight()/2);

JPanel panel = new JPanel();

JScrollPane pane = new JScrollPane();

JScrollPane pane2 = new JScrollPane();

final JTextArea area = new JTextArea();

final JTextArea area2 = new JTextArea();

JComboBox combobox = new JComboBox(cases);

JComboBox combobox2 = new JComboBox(cases);

getContentPane().add(panel);

panel.setLayout(null);

JButton run = new JButton("Run");

run.setBounds(375, 450, 80, 30);

run.setToolTipText("Run the test");

run.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent event) {

final Thread t1 = new Thread(new Runnable(){

public void run() {

execute(index2, area2);

}

});

t1.start();

execute(index,area);

}

});

area.setLineWrap(true);

area.setWrapStyleWord(true);

pane.setBounds(40,21,200,400);

pane.getViewport().add(area);

area2.setLineWrap(true);

area2.setWrapStyleWord(true);

pane2.setBounds(250,21,200,400);

pane2.getViewport().add(area2);

combobox.setBounds(50,450,150,20);

combobox.setToolTipText("Single Threading Case");

combobox.setSelectedIndex(0);

combobox.addItemListener(new ItemListener(){

public void itemStateChanged(ItemEvent e) {

JComboBox combo = (JComboBox) e.getSource();

index = combo.getSelectedIndex();

}

});

combobox2.setBounds(200,450,150,20);

combobox2.setToolTipText("Single Threading Case");

combobox2.setSelectedIndex(0);

combobox2.addItemListener(new ItemListener(){

public void itemStateChanged(ItemEvent e) {

JComboBox combo = (JComboBox) e.getSource();

index2 = combo.getSelectedIndex();

}

});

/*Menu*/

JMenuBar menuBar = new JMenuBar();

JMenu menu = new JMenu("File");

menuBar.add(menu);

JMenuItem menuItem = new JMenuItem("Save");

menuItem.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent event) {

save.savefunction(area,area2);

}

});

menu.add(menuItem);

JMenuItem menuItem1 = new JMenuItem("Close");

menuItem1.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent event) {

/*Figure out how to close out of panel only */

}

});

menu.add(menuItem1);

menuBar.setBounds(0,0,500,20);

panel.add(menuBar);

panel.add(combobox);

panel.add(combobox2);

panel.add(pane);

panel.add(pane2);

panel.add(run);

this.setVisible(true);

}

public void execute(int index, JTextArea a){

a.append("Run" + "\n");

switch(index){

case 0: {

a.append("Barbershop \n");

@SuppressWarnings("unused")

Barbershop shop = new Barbershop(a);

break;

}

case 1: {

a.append("Barrier \n");

@SuppressWarnings("unused")

Barrier barrier = new Barrier(a);

break;

}

case 2: {

a.append("Barrier Deadlock \n");

@SuppressWarnings("unused")

Barrier_Deadlock barrier2 = new Barrier_Deadlock(a);

break;

}

case 3: {

a.append("Barrier Deadlock2 \n");

@SuppressWarnings("unused")

Barrier_Deadlock2 barrier3 = new Barrier_Deadlock2(a);

break;

}

case 4: {

a.append("Building H2O \n");

@SuppressWarnings("unused")

Building_H2O h2o = new Building_H2O(a);

break;

}

case 5: {

a.append("Dining Philosophers \n");

@SuppressWarnings("unused")

Dining_Philosophers philos = new Dining_Philosophers(a);

break;

}

case 6: {

a.append("Dining Savages \n");

@SuppressWarnings("unused")

Dining_Savages savage = new Dining_Savages(a);

break;

}

case 7: {

a.append("Exclusive Queue \n");

@SuppressWarnings("unused")

Exclusive_Queue queue2 = new Exclusive_Queue(a);

break;

}

case 8: {

a.append("Multicar Roller Coaster \n");

@SuppressWarnings("unused")

Multicar_Roller_Coaster mrollerc = new Multicar_Roller_Coaster(a);

break;

}

case 9: {

a.append("Multiplex \n");

@SuppressWarnings("unused")

Multiplex multi = new Multiplex(a);

break;

}

case 10: {

a.append("Multiplex no Semaphore \n");

@SuppressWarnings("unused")

Multiplex_noSemaphore multi2 = new Multiplex_noSemaphore(a);

break;

}

case 11: {

a.append("Multiplex Synchronized Methods \n");

@SuppressWarnings("unused")

Multiplex_synchronized_methods multisynch = new Multiplex_synchronized_methods(

a);

break;

}

case 12: {

a.append("Mutex \n");

@SuppressWarnings("unused")

Mutex mutex = new Mutex(a);

break;

}

case 13: {

a.append("No Starve Mutex \n");

@SuppressWarnings("unused")

No_Starve_Mutex nostarvemutex = new No_Starve_Mutex(a);

break;

}

case 14: {

a.append("Producer Consumer \n");

@SuppressWarnings("unused")

Producer_Consumer p_c = new Producer_Consumer(a);

break;

}

case 15: {

a.append("Queue \n");

@SuppressWarnings("unused")

Queue queue = new Queue(a);

break;

}

case 16: {

a.append("Reader Writer \n");

@SuppressWarnings("unused")

Reader_Writer readwrite = new Reader_Writer(a);

break;

}

case 17: {

a.append("Rendezvous \n");

@SuppressWarnings("unused")

Rendezvous ren = new Rendezvous(a);

break;

}

case 18: {

a.append("Reusable Barrier \n");

@SuppressWarnings("unused")

Reusable_Barrier barrier4 = new Reusable_Barrier(a);

break;

}

case 19: {

a.append("River Crossing \n");

@SuppressWarnings("unused")

River_Crossing riverc = new River_Crossing(a);

break;

}

case 20: {

a.append("Roller Coaster \n");

@SuppressWarnings("unused")

Roller_Coaster rollerc = new Roller_Coaster(a);

break;

}

case 21: {

a.append("Sushi Bar \n");

@SuppressWarnings("unused")

Sushi_Bar sushi = new Sushi_Bar(a);

break;

}

case 22: {

a.append("Tanenbaums Solution \n");

@SuppressWarnings("unused")

Tanenbaums_Solution tanenbaum = new Tanenbaums_Solution(a);

break;

}

}

}

}

2 MainDriver.java

package drivers;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JFrame;

import javax.swing.JButton;

import javax.swing.JPanel;

import java.awt.Dimension;

import java.awt.Toolkit;

public class MainDriver extends JFrame{

/**

*

*/

private static final long serialVersionUID = 1L;

public MainDriver() {

setSize(200, 350);

setTitle("Little Book of Semaphore");

setDefaultCloseOperation(EXIT_ON_CLOSE);

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width/2 - getWidth()/2,

size.height/2 - getHeight()/2);

JPanel panel = new JPanel();

getContentPane().add(panel);

panel.setLayout(null);

/*exit button*/

JButton exit = new JButton("Exit");

exit.setBounds(50, 250, 80, 30);

exit.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

System.exit(0);

}

});

/*singledriver button*/

JButton subdriver1 = new JButton("Single");

subdriver1.setBounds(50,100,80,30);

subdriver1.setToolTipText("Single text area threading case test");

subdriver1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event){

@SuppressWarnings("unused")

SingleDriver driver1 = new SingleDriver();

}

});

/*doubledriver button*/

JButton subdriver2 = new JButton("Double");

subdriver2.setBounds(50,150,80,30);

subdriver2.setToolTipText("Double text area threading case test");

subdriver2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event){

@SuppressWarnings("unused")

DoubleDriver driver2 = new DoubleDriver();

}

});

panel.add(subdriver1);

panel.add(subdriver2);

panel.add(exit);

}

public static void main(String[] args) {

MainDriver mainscreen = new MainDriver();

mainscreen.setVisible(true);

}

}

3 SaveDriver.java

package drivers;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedWriter;

import java.io.FileWriter;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

public class SaveDriver extends JFrame {

private static final long serialVersionUID = 1L;

JTextField inputarea = new JTextField();

JButton savebutton = new JButton("Save");

public SaveDriver() {

setSize(450, 200);

setTitle("Save");

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width / 2 - getWidth() / 2, size.height / 2

- getHeight() / 2);

JPanel panel = new JPanel();

getContentPane().add(panel);

panel.setLayout(null);

JLabel label = new JLabel("Enter in file name: ");

label.setBounds(5, 10, 150, 20);

inputarea.setBounds(120, 10, 300, 20);

savebutton.setBounds(325, 115, 80, 30);

panel.add(label);

panel.add(inputarea);

panel.add(savebutton);

}

public void ifButtonclicked() {

this.setVisible(false);

}

public void savefunction(JTextArea a) {

final String areaA = a.getText();

this.setVisible(true);

savebutton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

final String filename = inputarea.getText();

ifButtonclicked();

try {

FileWriter fstream = new FileWriter(filename);

BufferedWriter out = new BufferedWriter(fstream);

out.write(areaA);

out.close();

} catch (Exception e) {

System.err.println("Error: " + e.getMessage());

}

}

});

}

public void savefunction(JTextArea a, JTextArea b) {

final String areaA = a.getText();

final String areaB = b.getText();

this.setVisible(true);

savebutton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

final String filename = inputarea.getText();

ifButtonclicked();

try {

FileWriter fstream = new FileWriter(filename);

BufferedWriter out = new BufferedWriter(fstream);

out.write(areaA);

out.write(areaB);

out.close();

} catch (Exception e) {

System.err.println("Error: " + e.getMessage());

}

}

});

}

}

4 SingleDriver.java

package drivers;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ItemEvent;

import java.awt.event.ItemListener;

import javax.swing.JButton;

import javax.swing.JComboBox;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import cases.*;

public class SingleDriver extends JFrame {

final String[] cases = { "Barbershop", "Barrier", "Barrier Deadlock",

"Barrier Deadlock2", "Building H2O", "Dining Philosophers",

"Dining Savages", "Exclusive Queue", "Multicar Roller Coaster",

"Multiplex", "Multiplex no Semaphore", "Multiplex Synchronized",

"Mutex", "No Starve Mutex", "Producer Consumer", "Queue",

"Reader Writer", "Rendezvous", "Reusable Barrier",

"River Crossing", "Roller Coaster", "Sushi Bar",

"Tenenbaums Solution" };

private static final long serialVersionUID = 1L;

int index = 0;

SaveDriver save = new SaveDriver();

public SingleDriver() {

setSize(500, 600);

setTitle("Single Threading Test");

Toolkit toolkit = getToolkit();

Dimension size = toolkit.getScreenSize();

setLocation(size.width / 2 - getWidth() / 2, size.height / 2

- getHeight() / 2);

JPanel panel = new JPanel();

JScrollPane pane = new JScrollPane();

final JTextArea area = new JTextArea();

JComboBox combobox = new JComboBox(cases);

getContentPane().add(panel);

panel.setLayout(null);

/* Run button */

JButton run = new JButton("Run");

run.setBounds(250, 450, 80, 30);

run.setToolTipText("Run the test");

run.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

run(index, area);

}

});

/* JTextArea */

area.setLineWrap(true);

area.setWrapStyleWord(true);

pane.setBounds(40, 21, 400, 400);

pane.getViewport().add(area);

/* Combobox */

combobox.setBounds(50, 450, 150, 20);

combobox.setToolTipText("Single Threading Case");

combobox.setSelectedIndex(0);

combobox.setMaximumRowCount(5);

combobox.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent e) {

JComboBox combo = (JComboBox) e.getSource();

index = combo.getSelectedIndex();

}

});

/* Menu */

JMenuBar menuBar = new JMenuBar();

JMenu menu = new JMenu("File");

menuBar.add(menu);

JMenuItem menuItem = new JMenuItem("Save");

menuItem.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

save.savefunction(area);

}

});

menu.add(menuItem);

JMenuItem menuItem1 = new JMenuItem("Close");

menuItem1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

/* Figure out how to close out of panel only */

}

});

menu.add(menuItem1);

menuBar.setBounds(0, 0, 500, 20);

/* Add content to panel */

panel.add(menuBar);

panel.add(combobox);

panel.add(pane);

panel.add(run);

this.setVisible(true);

}

public void run(int index, JTextArea a) {

a.append("Run ");

switch (index) {

case 0: {

a.append("Barbershop \n");

@SuppressWarnings("unused")

Barbershop shop = new Barbershop(a);

break;

}

case 1: {

a.append("Barrier \n");

@SuppressWarnings("unused")

Barrier barrier = new Barrier(a);

break;

}

case 2: {

a.append("Barrier Deadlock \n");

@SuppressWarnings("unused")

Barrier_Deadlock barrier2 = new Barrier_Deadlock(a);

break;

}

case 3: {

a.append("Barrier Deadlock2 \n");

@SuppressWarnings("unused")

Barrier_Deadlock2 barrier3 = new Barrier_Deadlock2(a);

break;

}

case 4: {

a.append("Building H2O \n");

@SuppressWarnings("unused")

Building_H2O h2o = new Building_H2O(a);

break;

}

case 5: {

a.append("Dining Philosophers \n");

@SuppressWarnings("unused")

Dining_Philosophers philos = new Dining_Philosophers(a);

break;

}

case 6: {

a.append("Dining Savages \n");

@SuppressWarnings("unused")

Dining_Savages savage = new Dining_Savages(a);

break;

}

case 7: {

a.append("Exclusive Queue \n");

@SuppressWarnings("unused")

Exclusive_Queue queue2 = new Exclusive_Queue(a);

break;

}

case 8: {

a.append("Multicar Roller Coaster \n");

@SuppressWarnings("unused")

Multicar_Roller_Coaster mrollerc = new Multicar_Roller_Coaster(a);

break;

}

case 9: {

a.append("Multiplex \n");

@SuppressWarnings("unused")

Multiplex multi = new Multiplex(a);

break;

}

case 10: {

a.append("Multiplex no Semaphore \n");

@SuppressWarnings("unused")

Multiplex_noSemaphore multi2 = new Multiplex_noSemaphore(a);

break;

}

case 11: {

a.append("Multiplex Synchronized Methods \n");

@SuppressWarnings("unused")

Multiplex_synchronized_methods multisynch = new Multiplex_synchronized_methods(

a);

break;

}

case 12: {

a.append("Mutex \n");

@SuppressWarnings("unused")

Mutex mutex = new Mutex(a);

break;

}

case 13: {

a.append("No Starve Mutex \n");

@SuppressWarnings("unused")

No_Starve_Mutex nostarvemutex = new No_Starve_Mutex(a);

break;

}

case 14: {

a.append("Producer Consumer \n");

@SuppressWarnings("unused")

Producer_Consumer p_c = new Producer_Consumer(a);

break;

}

case 15: {

a.append("Queue \n");

@SuppressWarnings("unused")

Queue queue = new Queue(a);

break;

}

case 16: {

a.append("Reader Writer \n");

@SuppressWarnings("unused")

Reader_Writer readwrite = new Reader_Writer(a);

break;

}

case 17: {

a.append("Rendezvous \n");

@SuppressWarnings("unused")

Rendezvous ren = new Rendezvous(a);

break;

}

case 18: {

a.append("Reusable Barrier \n");

@SuppressWarnings("unused")

Reusable_Barrier barrier4 = new Reusable_Barrier(a);

break;

}

case 19: {

a.append("River Crossing \n");

@SuppressWarnings("unused")

River_Crossing riverc = new River_Crossing(a);

break;

}

case 20: {

a.append("Roller Coaster \n");

@SuppressWarnings("unused")

Roller_Coaster rollerc = new Roller_Coaster(a);

break;

}

case 21: {

a.append("Sushi Bar \n");

@SuppressWarnings("unused")

Sushi_Bar sushi = new Sushi_Bar(a);

break;

}

case 22: {

a.append("Tanenbaums Solution \n");

@SuppressWarnings("unused")

Tanenbaums_Solution tanenbaum = new Tanenbaums_Solution(a);

break;

}

}

}

}

3 PURE

1 Barbershop.java

package PURE;

import java.util.concurrent.Semaphore;

public class Barbershop {

int customers = 0;

int n = 4; /* needed to be added: number of chairs */

Semaphore mutex = new Semaphore (1);

Semaphore customer = new Semaphore (0);

Semaphore barber = new Semaphore(0);

public void barbershopcustomer() throws InterruptedException{

mutex.acquire();

if (customers == n+1){

mutex.release();

/* balk(); */

}

customers = customers + 1;

mutex.release();

customer.release();

barber.acquire();

/* getHairCut(); */

mutex.acquire();

customers = customers + 1;

mutex.release();

}

public void barbershopbarber() throws InterruptedException{

customer.acquire();

barber.release();

/* cutHair(); */

}

}

2

3 Barrier.java

package PURE;

import java.util.concurrent.Semaphore;

public class Barrier {

final Semaphore aArrived = new Semaphore(0);

final Semaphore bArrived = new Semaphore(0);

final Semaphore mutex = new Semaphore(1);

final Semaphore barrier = new Semaphore(0);

int count = 0;

int n = 1; //number of threads

public void execute1()throws InterruptedException{

/* statement a1 */

aArrived.release();

bArrived.acquire();

/* statement a2 */

barrierwait();

}

public void execute2() throws InterruptedException{

/* statement b1 */

bArrived.release();

aArrived.acquire();

/* statement b2 */

barrierwait();

}

public void barrierwait() throws InterruptedException{

mutex.acquire();

count = count + 1;

mutex.release();

if (count == n){

barrier.release();

}

barrier.acquire();

barrier.release();

/* critical point */

}

}

Barrier_Deadlock.java

package PURE;

import java.util.concurrent.Semaphore;

public class Barrier_Deadlock {

final Semaphore aArrived = new Semaphore(0);

final Semaphore bArrived = new Semaphore(0);

final Semaphore mutex = new Semaphore(1);

final Semaphore barrier = new Semaphore(0);

int count = 0;

int n = 1; // number of threads

public void execute1() throws InterruptedException {

/* statement a1 */

aArrived.release();

bArrived.acquire();

/* statement a2 */

barrierwait();

}

public void execute2() throws InterruptedException {

/* statement b1 */

bArrived.release();

aArrived.acquire();

/* statement b2 */

barrierwait();

}

public void barrierwait() throws InterruptedException {

mutex.acquire();

count = count + 1;

mutex.release();

if (count == n) {

barrier.release();

}

barrier.acquire();

/* critical point */

}

}

4 Barrier_Deadlock2.java

package PURE;

import java.util.concurrent.Semaphore;

public class Barrier_Deadlock2 {

final Semaphore aArrived = new Semaphore(0);

final Semaphore bArrived = new Semaphore(0);

final Semaphore mutex = new Semaphore(1);

final Semaphore barrier = new Semaphore(0);

int count = 0;

int n = 1; // number of threads

public void execute1() throws InterruptedException {

/* statement a1 */

aArrived.release();

bArrived.acquire();

/* statement a2 */

barrierwait();

}

public void execute2() throws InterruptedException {

/* statement b1 */

bArrived.release();

aArrived.acquire();

/* statement b2 */

barrierwait();

}

public void barrierwait() throws InterruptedException {

mutex.acquire();

count = count + 1;

if (count == n) {

barrier.release();

}

barrier.acquire();

barrier.release();

mutex.release();

/* critical point */

}

}

5 Building_H2O.java

package PURE;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.Semaphore;

public class Building_H2O {

Semaphore mutex = new Semaphore(1);

int oxygen = 0;

int hydrogen = 0;

CyclicBarrier barrier = new CyclicBarrier(3);

/* Unsure if barrier will reset itself when 3 threads

* have arrived. This should be tested. If not, then Oxygen

* should have a barrier.reset(); after it is released from

* barrier.

*/

Semaphore oxyQueue = new Semaphore(0);

Semaphore hydroQueue = new Semaphore(0);

public void Oxygen() throws InterruptedException, BrokenBarrierException{

mutex.acquire();

oxygen = oxygen + 1;

if(hydrogen >= 2){

hydroQueue.release(2);

hydrogen = hydrogen - 2;

oxyQueue.release();

oxygen = oxygen - 1;

}

else{

mutex.release();

}

oxyQueue.acquire();

/* bond(); */

barrier.await();

mutex.release();

}

public void Hydrogen() throws InterruptedException, BrokenBarrierException{

mutex.acquire();

hydrogen = hydrogen + 1;

if(hydrogen >= 2 && oxygen >= 1 ){

hydroQueue.release(2);

hydrogen = hydrogen - 2;

oxyQueue.release();

oxygen = oxygen - 1;

}

else{

mutex.release();

}

hydroQueue.acquire();

/* bond(); */

barrier.await();

}

}

6 Bus_Problem.java

package PURE;

import java.util.concurrent.Semaphore;

public class Bus_Problem {

int riders = 0;

Semaphore mutex = new Semaphore(1);

Semaphore multiplex = new Semaphore(50);

Semaphore bus = new Semaphore(0);

Semaphore allAboard = new Semaphore(0);

public void bus() throws InterruptedException {

mutex.acquire();

if (riders > 0) {

bus.release(); /* and pass the mutex */

allAboard.acquire(); /* and get the mutex back */

}

mutex.release();

/* depart(); */

}

public void riders() throws InterruptedException {

multiplex.acquire();

mutex.acquire();

riders = riders + 1;

mutex.release();

bus.acquire(); /* and get the mutex */

multiplex.release();

/* boardBus(); */

riders = riders - 1;

if(riders == 0){

allAboard.release();

}

else{

bus.release(); /* and pass the mutex */

}

}

}

7 Bus_Problem_Alt.java

package PURE;

import java.util.concurrent.Semaphore;

public class Bus_Problem_Alt {

int waiting = 0;

Semaphore mutex = new Semaphore(1);

Semaphore bus = new Semaphore(0);

Semaphore boarded = new Semaphore(0);

public void bus() throws InterruptedException {

mutex.acquire();

int n = Math.min(waiting, 50);

for (int i = 0; i < n; i++) {

bus.release();

boarded.acquire();

}

waiting = Math.max(waiting - 50, 0);

mutex.release();

/* depart(); */

}

public void riders() throws InterruptedException {

mutex.acquire();

waiting = waiting + 1;

mutex.release();

bus.acquire();

/* board(); */

boarded.release();

}

}

8 Cigarette_Smokers_Deadlock.java

package PURE;

import java.util.concurrent.Semaphore;

public class Cigarette_Smokers_Deadlock {

Semaphore agentSem = new Semaphore(1);

Semaphore tobacco = new Semaphore(0);

Semaphore paper = new Semaphore (0);

Semaphore match = new Semaphore(0);

public void AgentA() throws InterruptedException{

agentSem.acquire();

tobacco.release();

paper.release();

}

public void AgentB() throws InterruptedException{

agentSem.acquire();

paper.release();

match.release();

}

public void AgentC() throws InterruptedException{

agentSem.acquire();

tobacco.release();

match.release();

}

/* Dead lock solutions */

public void SmokerWithMatches() throws InterruptedException{

tobacco.acquire();

paper.acquire();

agentSem.release();

}

public void SmokerWithTobacco() throws InterruptedException{

paper.acquire();

match.acquire();

agentSem.release();

}

public void SmokerWithPaper() throws InterruptedException{

tobacco.acquire();

match.acquire();

agentSem.release();

}

}

9 Dining_Philosophers.java

package PURE;

import java.util.concurrent.Semaphore;

/* uses 5 threads */

public class Dining_Philosophers {

Semaphore fork[];

Semaphore footman = new Semaphore(4);

public Dining_Philosophers(){

for(int i = 0; i0){

followers = followers - 1;

followerQueue.release();

}

else{

leaders = leaders + 1;

mutex.release();

leaderQueue.acquire();

}

/* dance(); */

rendezvous.acquire();

mutex.release();

}

public void followers() throws InterruptedException{

mutex.acquire();

if(leaders >0){

leaders = leaders - 1;

leaderQueue.release();

}

else{

followers = followers + 1;

mutex.release();

followerQueue.acquire();

}

/* dance(); */

rendezvous.release();

}

}

12 Extended_Child_Care.java

package PURE;

import java.util.concurrent.Semaphore;

public class Extended_Child_Care {

int children, adults, waiting, leaving = 0;

Semaphore mutex = new Semaphore(1);

Semaphore childQueue = new Semaphore(0);

Semaphore adultQueue = new Semaphore(0);

public void child() throws InterruptedException {

mutex.acquire();

if(children < (3*adults)){

children = children + 1;

mutex.release();

}

else{

waiting = waiting + 1;

mutex.release();

childQueue.acquire();

}

/* critical section */

mutex.acquire();

children = children - 1;

if (leaving prudes){

status = "transition to heathens";

prudeTurn.acquire();

}

mutex.release();

heathenQueue.acquire();

}

else if (status.equals("transition to heathens")){

mutex.release();

heathenQueue.acquire();

}

else{

mutex.release();

}

/* cross the field */

mutex.acquire();

heathens = heathens - 1;

if(heathens == 0){

if(status.equals("transition to prudes")){

prudeTurn.release();

}

if (status.equals("prudes rule")){

prudeQueue.release(prudes);

status = "prudes rule";

}

else{

status = "neutral";

}

}

if(status.equals("heathens rule")){

if(prudes > heathens){

status = "transition to prudes";

heathenTurn.acquire();

}

}

mutex.release();

}

}

18 Multicar_Roller_Coaster.java

package PURE;

/* This classes logic is unsound as there is a

* discrepancy as to how int i should be treated.

* Should each thread have an int i, or should it

* be global.

* Each car gets its own i call j, it takes the value i, then

* increments it, at any one time there should only be m

* cars, if more cars(threads) are implemented the algorithm

* will not work.

*/

import java.util.concurrent.Semaphore;

public class Multicar_Roller_Coaster {

Semaphore mutex = new Semaphore(1);

Semaphore mutex2 = new Semaphore(1);

Semaphore mutexcarnumber = new Semaphore(1);

int boarders = 0;

int unboarders = 0;

int C = 2; /* c = number of spots in a car */

int m = 6; /* m = number of cars per roller coaster */

int i = 0;

Semaphore boardQueue = new Semaphore(0);

Semaphore unboardQueue = new Semaphore(0);

Semaphore allAboard = new Semaphore(0);

Semaphore allAshore = new Semaphore(0);

Semaphore loadingArea [];

Semaphore unloadingArea [];

public Multicar_Roller_Coaster(){

for(int k = 0; k= 2){

hackerQueue.release(2);

serfQueue.release(2);

serfs = serfs - 2;

hackers = 0;

isCaptain = true;

}

else{

mutex.release(); /* captain keeps the mutex */

}

hackerQueue.wait();

/* board(); */

barrier.await();

if(isCaptain){

/*rowBoat(); */

mutex.release(); /* captain releases the mutex */

}

}

public void Serfs() throws InterruptedException, BrokenBarrierException{

boolean isCaptain = false;

mutex.acquire();

serfs = serfs + 1;

if(serfs == 4){

serfQueue.release(4);

serfs = 0;

isCaptain = true;

}

else if(serfs == 2 && hackers >= 2){

serfQueue.release(2);

hackerQueue.release(2);

hackers = hackers - 2;

serfs = 0;

isCaptain = true;

}

else{

mutex.release(); /* captain keeps the mutex */

}

serfQueue.wait();

/* board(); */

barrier.await();

if(isCaptain){

/*rowBoat(); */

mutex.release(); /* captain releases the mutex */

}

}

}

30 Roller_Coaster.java

package PURE;

import java.util.concurrent.Semaphore;

public class Roller_Coaster {

Semaphore mutex = new Semaphore(1);

Semaphore mutex2 = new Semaphore(1);

int boarders = 0;

int unboarders = 0;

int C = 2; /* c = number of spots in a roller coaster */

Semaphore boardQueue = new Semaphore(0);

Semaphore unboardQueue = new Semaphore(0);

Semaphore allAboard = new Semaphore(0);

Semaphore allAshore = new Semaphore(0);

public void car() throws InterruptedException{

/* load(); */

boardQueue.release(C);

allAboard.acquire();

/* run(); */

/* unload(); */

unboardQueue.release(C);

allAshore.acquire();

}

public void passenger() throws InterruptedException{

boardQueue.acquire();

/* board */

mutex.acquire();

boarders = boarders + 1;

if (boarders == C){

allAboard.release();

boarders = 0;

}

mutex.release();

unboardQueue.acquire();

/* unboard(); */

mutex2.acquire();

unboarders = unboarders + 1;

if(unboarders == C){

allAshore.release();

unboarders = 0;

}

mutex2.release();

}

}

31 Sushi_Bar.java

package PURE;

import java.util.concurrent.Semaphore;

public class Sushi_Bar {

int eating,waiting = 0;

Semaphore mutex = new Semaphore(1);

Semaphore block = new Semaphore(0);

Boolean must_wait = false;

public void sushi() throws InterruptedException{

mutex.acquire();

if(must_wait){

waiting = waiting + 1;

mutex.release();

block.acquire();

}

else{

eating = eating + 1;

must_wait = (eating == 5);

mutex.release();

}

/* eat sushi */

mutex.acquire();

eating = eating - 1;

if(eating == 0){

int n = Math.min(5,waiting);

waiting = waiting - n;

eating = eating - n;

must_wait = (eating == 5);

block.release(n);

}

mutex.release();

}

}

32 Sushi_Bar_Alt.java

package PURE;

import java.util.concurrent.Semaphore;

public class Sushi_Bar_Alt {

int eating, waiting = 0;

Semaphore mutex = new Semaphore(1);

Semaphore block = new Semaphore(0);

Boolean must_wait = false;

public void sushi() throws InterruptedException {

mutex.acquire();

if (must_wait) {

waiting = waiting + 1;

mutex.release();

block.acquire(); /* when we resume, we have the mutex */

waiting = waiting - 1;

}

eating = eating + 1;

must_wait = (eating == 5);

if(!must_wait){

block.release(); /* and pass the mutex */

}

else{

mutex.release();

}

/* eat sushi */

mutex.acquire();

eating = eating - 1;

if(eating == 0){

must_wait = false;

}

if(!must_wait){

block.release(); /* and pass the mutex */

}

else{

mutex.release();

}

}

}

33 Tanenbaums_Solution.java

package PURE;

import java.util.concurrent.Semaphore;

/* uses 5 threads */

public class Tanenbaums_Solution {

public String state[];

Semaphore sem[];

Semaphore mutex = new Semaphore(1);

public Tanenbaums_Solution(){

for(int i = 0; i 0 && students < 50) {

dean = "waiting";

mutex.release();

lieIn.acquire(); /* and get mutex from the student. */

}

/* students must be 0 or >=50 */

if (students >= 50) {

dean = "in the room";

/* breakup(); */

turn.acquire(); /* lock the turnstile */

mutex.release();

clear.acquire(); /* and get mutex from the student */

turn.release(); /* unlock the turnstile */

}

else { /* students must be 0 */

/* search(); */

}

dean = "not here";

mutex.release();

}

public void student() throws InterruptedException {

mutex.acquire();

if (dean.equals("in the room")) {

mutex.release();

turn.acquire();

turn.release();

mutex.acquire();

}

students = students + 1;

if (students == 50 && dean.equals("waiting")) {

lieIn.release(); /* and pass mutex to the dean */

}

else {

mutex.release();

}

/* party(); */

mutex.acquire();

students = students - 1;

if (students == 0 && dean.equals("waiting")) {

lieIn.release(); /* and pass mutex to the dean */

}

else if (students == 0 && dean.equals("in the room")) {

clear.release(); /* and pass mutex to the dean */

}

else {

mutex.release();

}

}

}

35 The_Santa_Claus.java

package PURE;

import java.util.concurrent.Semaphore;

public class The_Santa_Claus {

int elves = 0;

int reindeer = 0;

Semaphore santaSem = new Semaphore(0);

Semaphore reindeerSem = new Semaphore(0);

Semaphore elfTex = new Semaphore(1);

Semaphore mutex = new Semaphore(1);

public void Santa() throws InterruptedException{

santaSem.acquire();

mutex.acquire();

if(reindeer == 9){

/* prepareSleigh(); */

reindeerSem.release(9);

}

else if (elves == 3){

/* helpElves() */

}

mutex.release();

}

public void reindeer() throws InterruptedException{

mutex.acquire();

reindeer = reindeer + 1;

if(reindeer == 9){

santaSem.release();

}

mutex.release();

reindeerSem.acquire();

/* getHitched(); */

}

public void elves() throws InterruptedException {

elfTex.acquire();

mutex.acquire();

elves = elves + 1;

if (elves == 3) {

santaSem.release();

}

else {

elfTex.release();

}

mutex.release();

/* getHelp(); */

mutex.acquire();

elves = elves - 1;

if (elves == 0) {

elfTex.release();

}

mutex.release();

}

}

Glossary

Driver - Parts of the application that run all the features and execute other drivers and cases

Main Driver - Driver that starts all the sub drivers

Sub Driver - Drivers that include outputs and features used for running cases

Case - Coded examples of semaphore and thread usage that are able to execute

Semaphore- The classic method for restricting access to shared resources (e.g. storage) in a multi-processing environment. ()

Index

case, 14, 15, 16, 17, 18

Case, 60, 64, 65, 67, 68, 69, 71, 72, 177

Cases, 19, 24, 25, 26, 27, 29, 32, 60, 62, 63, 64, 69

Double Driver, 22, 26, 27, 29, 62, 63

Driver, 3, 4, 9, 19, 20, 22, 23, 24, 26, 27, 29, 59, 60, 63, 67, 68, 69, 70, 71, 72, 73, 177

drivers, 13, 14, 15, 16, 18, 19, 66, 177

hyperthreading, 62, 65

Logging Thread, 32, 33

main driver, 14, 15, 16, 18, 19

Main driver, 177

Main Driver, 19, 20, 22, 23, 26, 59, 60, 62, 67, 68, 69, 72, 73

Save Driver, 26, 29

Semaphore, 12, 13, 66, 177

semaphores, 62

Single Driver, 23, 24, 25, 26, 27, 29, 62, 63

Sub driver, 177

Sub Driver, 67, 68, 69, 72

Sub Drivers, 19, 22, 23, 26, 32, 59

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download