Download Chapter 4 System Design - University of Scranton: Computing

Document related concepts
no text concepts found
Transcript
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
The Little Book of Semaphores – Threading Learning Tool
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
2
The Little Book of Semaphores – Threading Learning Tool
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
3
The Little Book of Semaphores – Threading Learning Tool
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
4
The Little Book of Semaphores – Threading Learning Tool
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
5
The Little Book of Semaphores – Threading Learning Tool
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
6
The Little Book of Semaphores – Threading Learning Tool
The_Santa_Claus.java ....................................................................................................................... 175
Chapter 8 Glossary .................................................................................................................................... 177
Chapter 9 Index ......................................................................................................................................... 178
Chapter 1 Extended Abstract
Context
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.
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
7
The Little Book of Semaphores – Threading Learning Tool
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.
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.
Overview
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.
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
8
The Little Book of Semaphores – Threading Learning Tool
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.
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.
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
9
The Little Book of Semaphores – Threading Learning Tool
of the work will come in the form of creating the GUI to drive and present the classes that are to
be written.
Chapter 2 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
10
The Little Book of Semaphores – Threading Learning Tool
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
11
The Little Book of Semaphores – Threading Learning Tool
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".
Buy SmartDraw!- purchased copies print this
document without a watermark.
Visit www.smartdraw.com or call 1-800-768-3729.
Chapter 3 Requirements Specifications
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.
12
The Little Book of Semaphores – Threading Learning Tool
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.
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
13
The Little Book of Semaphores – Threading Learning Tool
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.
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"
14
The Little Book of Semaphores – Threading Learning Tool
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
15
The Little Book of Semaphores – Threading Learning Tool
the ability of a user to learn from this tool and be able significantly understand the uses of
semaphores and threads.
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
16
The Little Book of Semaphores – Threading Learning Tool
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.
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
17
The Little Book of Semaphores – Threading Learning Tool
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.
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
18
The Little Book of Semaphores – Threading Learning Tool
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.
Chapter 4 System Design
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
19
The Little Book of Semaphores – Threading Learning Tool
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.
Main Driver
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.
20
The Little Book of Semaphores – Threading Learning Tool
Abstract Specification
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.
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.
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
21
The Little Book of Semaphores – Threading Learning Tool
"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.
Interface Design
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.
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.
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.
22
The Little Book of Semaphores – Threading Learning Tool
Single Driver
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.
23
The Little Book of Semaphores – Threading Learning Tool
Abstract Specification
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.
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.
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.
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"
24
The Little Book of Semaphores – Threading Learning Tool
Action Listener which when activated will open the SaveDriver.class. The Menu Bar sits 0 pixels
from the left and 0 pixels down.
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.
Interface Design
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.
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.
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.
25
The Little Book of Semaphores – Threading Learning Tool
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.
Double Driver
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.
26
The Little Book of Semaphores – Threading Learning Tool
Abstract Specification
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.
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
27
The Little Book of Semaphores – Threading Learning Tool
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.
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.
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.
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.
28
The Little Book of Semaphores – Threading Learning Tool
Interface Design
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.
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.
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.
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.
Save Driver
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
29
The Little Book of Semaphores – Threading Learning Tool
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.
Abstract Specification
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.
30
The Little Book of Semaphores – Threading Learning Tool
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.
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.
Interface Design
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.
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.
31
The Little Book of Semaphores – Threading Learning Tool
Cases
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.
Abstract Specification
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.
32
The Little Book of Semaphores – Threading Learning Tool
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.
Algorithms Design
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
33
The Little Book of Semaphores – Threading Learning Tool
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
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()
34
The Little Book of Semaphores – Threading Learning Tool
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()
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
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.
35
The Little Book of Semaphores – Threading Learning Tool
# 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()
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()
36
The Little Book of Semaphores – Threading Learning Tool
2 followerQueue.wait()
3 dance()
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()
37
The Little Book of Semaphores – Threading Learning Tool
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.
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:
38
The Little Book of Semaphores – Threading Learning Tool
1 items.wait()
2 mutex.wait()
3 event = buffer.get()
4 mutex.signal()
5 event.process()
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()
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()
39
The Little Book of Semaphores – Threading Learning Tool
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()
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()
40
The Little Book of Semaphores – Threading Learning Tool
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()
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
41
The Little Book of Semaphores – Threading Learning Tool
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()
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()
42
The Little Book of Semaphores – Threading Learning Tool
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()
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:
43
The Little Book of Semaphores – Threading Learning Tool
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()
Santa Claus
Variables:
1 elves = 0
2 reindeer = 0
3 santaSem = Semaphore(0)
4 reindeerSem = Semaphore(0)
44
The Little Book of Semaphores – Threading Learning Tool
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()
45
The Little Book of Semaphores – Threading Learning Tool
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()
46
The Little Book of Semaphores – Threading Learning Tool
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
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)
47
The Little Book of Semaphores – Threading Learning Tool
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()
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
48
The Little Book of Semaphores – Threading Learning Tool
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()
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:
49
The Little Book of Semaphores – Threading Learning Tool
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()
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)
Modus Hall
Variables:
1 heathens = 0
2 prudes = 0
3 status = ’neutral’
4 mutex = Semaphore(1)
5 heathenTurn = Semaphore(1)
6 prudeTurn = Semaphore(1)
50
The Little Book of Semaphores – Threading Learning Tool
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()
51
The Little Book of Semaphores – Threading Learning Tool
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()
52
The Little Book of Semaphores – Threading Learning Tool
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()
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()
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:
53
The Little Book of Semaphores – Threading Learning Tool
6 waiting++
7 mutex.signal()
8 childQueue.wait()
9
10 # critical section
11
12 mutex.wait()
13 children-14 if leaving and children <= 3 * (adults-1):
15 leaving-16 adults-17 adultQueue.signal()
18 mutex.signal()
Adults Code:
1 mutex.wait()
2 adults++
3 if waiting:
4 n = min(3, waiting)
5 childQueue.signal(n)
6 waiting -= n
7 children += n
8 mutex.signal()
9
10 # critical section
11
12 mutex.wait()
13 if children <= 3 * (adults-1):
14 adults-15 mutex.signal()
16 else:
17 leaving++
18 mutex.signal()
19 adultQueue.wait()
Room party
Variables:
1 students = 0
2 dean = ’not here’
3 mutex = Semaphore(1)
4 turn = Semaphore(1)
5 clear = Semaphore(0)
6 lieIn = Semaphore(0)
Dean Code:
54
The Little Book of Semaphores – Threading Learning Tool
1 mutex.wait()
2 if students > 0 and students < 50:
3 dean = ’waiting’
4 mutex.signal()
5 lieIn.wait() # and get mutex from the student.
6
7 # students must be 0 or >= 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
55
The Little Book of Semaphores – Threading Learning Tool
24 else:
25 mutex.signal()
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
Alternate Senate Bus Solution
Variables:
1 waiting = 0
2 mutex = new Semaphore(1)
3 bus = new Semaphore(0)
4 boarded = new Semaphore(0)
56
The Little Book of Semaphores – Threading Learning Tool
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()
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
57
The Little Book of Semaphores – Threading Learning Tool
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()
Dining Hall
Variables:
1 eating = 0
2 readyToLeave = 0
58
The Little Book of Semaphores – Threading Learning Tool
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()
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
59
The Little Book of Semaphores – Threading Learning Tool
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.
Chapter 5 Testing Design
Introduction
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.
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
60
The Little Book of Semaphores – Threading Learning Tool
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.
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
61
The Little Book of Semaphores – Threading Learning Tool
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.
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.
Testing
Testing List
Main Driver
Single Driver Button
Double Driver Button
Exit Button
62
The Little Book of Semaphores – Threading Learning Tool
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
63
The Little Book of Semaphores – Threading Learning Tool
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
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.
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.
64
The Little Book of Semaphores – Threading Learning Tool
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.
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.
65
The Little Book of Semaphores – Threading Learning Tool
Chapter 6 User Manual
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
66
The Little Book of Semaphores – Threading Learning Tool
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.
Introductory Manual
How to Use the System
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.
67
The Little Book of Semaphores – Threading Learning Tool
- 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!
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
68
The Little Book of Semaphores – Threading Learning Tool
Holds the Save and Close commands. Save will execute the Save Driver. Close will
currently do nothing.
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.
69
The Little Book of Semaphores – Threading Learning Tool
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.
70
The Little Book of Semaphores – Threading Learning Tool
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.
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.
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".
71
The Little Book of Semaphores – Threading Learning Tool
- 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."
System Reference Manual
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.
72
The Little Book of Semaphores – Threading Learning Tool
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.
Installation Information
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.
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
73
The Little Book of Semaphores – Threading Learning Tool
Chapter 7 Appendix
Cases
Barbershop.java
package cases;
import
import
import
import
java.awt.Dimension;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
import
import
import
import
import
import
import
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;
javax.swing.JPanel;
javax.swing.JTextArea;
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
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);
74
The Little Book of Semaphores – Threading Learning Tool
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<Thread> customers = new ArrayList<Thread>();
for (int i = 0; i < customeramount; i++) {
final Thread t1 = new Thread(new Runnable() {
75
The Little Book of Semaphores – Threading Learning Tool
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();
76
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
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);
77
The Little Book of Semaphores – Threading Learning Tool
int count = 0;
int n = 4; // number of threads
int threadcount = n;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Barrier(final JTextArea a) {
/* Threadgroup1 creation */
ArrayList<Thread> threadgroup1 = new ArrayList<Thread>();
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<Thread> threadgroup2 = new ArrayList<Thread>();
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();
}
}
});
78
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
79
The Little Book of Semaphores – Threading Learning Tool
Thread.sleep(50);
}
}
}
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Barrier_Deadlock(final JTextArea a) {
/* Threadgroup1 creation */
ArrayList<Thread> threadgroup1 = new ArrayList<Thread>();
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<Thread> threadgroup2 = new ArrayList<Thread>();
for (int i = 0; i < (threadcount / 2); i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
rendezvous2();
80
The Little Book of Semaphores – Threading Learning Tool
} 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();
}
81
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Barrier_Deadlock2(final JTextArea a) {
/* Threadgroup1 creation */
ArrayList<Thread> threadgroup1 = new ArrayList<Thread>();
for (int i = 0; i < (threadcount / 2); i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
82
The Little Book of Semaphores – Threading Learning Tool
try {
rendezvous1();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
threadgroup1.add(t1);
}
/* Threadgroup2 creation */
ArrayList<Thread> threadgroup2 = new ArrayList<Thread>();
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();
83
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
84
The Little Book of Semaphores – Threading Learning Tool
Building_H2O.java
package cases;
import
import
import
import
import
import
import
import
import
java.awt.Dimension;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.util.ArrayList;
java.util.concurrent.BrokenBarrierException;
java.util.concurrent.ConcurrentLinkedQueue;
java.util.concurrent.CyclicBarrier;
java.util.concurrent.Semaphore;
import
import
import
import
import
import
import
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;
javax.swing.JPanel;
javax.swing.JTextArea;
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
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 ");
85
The Little Book of Semaphores – Threading Learning Tool
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<Thread> oxygen = new ArrayList<Thread>();
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<Thread> hydrogen = new ArrayList<Thread>();
for (int i = 0; i < hydrogenamount; i++) {
86
The Little Book of Semaphores – Threading Learning Tool
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;
}
87
The Little Book of Semaphores – Threading Learning Tool
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);
88
The Little Book of Semaphores – Threading Learning Tool
}
}
Thread.sleep(50);
}
}
}
Dining_Philosophers.java
package cases;
import
import
import
import
java.awt.Dimension;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
import
import
import
import
import
import
import
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;
javax.swing.JPanel;
javax.swing.JTextArea;
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
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);
89
The Little Book of Semaphores – Threading Learning Tool
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<Thread> philosophers = new ArrayList<Thread>();
for (int i = 0; i < threadcount; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
get_forks(getphilosophernumber());
90
The Little Book of Semaphores – Threading Learning Tool
} 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();
91
The Little Book of Semaphores – Threading Learning Tool
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;
}
}
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Dining_Savages(final JTextArea a) {
ArrayList<Thread> savages = new ArrayList<Thread>();
for (int i = 0; i < threadcount - 1; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
92
The Little Book of Semaphores – Threading Learning Tool
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");
93
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
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);
94
The Little Book of Semaphores – Threading Learning Tool
Semaphore leaderQueue = new Semaphore(0);
Semaphore followerQueue = new Semaphore(0);
Semaphore rendezvous = new Semaphore(0);
int threadcount = 10;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Exclusive_Queue(final JTextArea a) {
/* leaders thread creation */
ArrayList<Thread> leader = new ArrayList<Thread>();
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<Thread> follower = new ArrayList<Thread>();
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();
}
}
});
95
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
96
The Little Book of Semaphores – Threading Learning Tool
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Modus_Hall(final JTextArea a){
/* Heathen thread creation */
ArrayList<Thread> heathen = new ArrayList<Thread>();
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<Thread> prude = new ArrayList<Thread>();
for (int i = 0; i < prudesamount; i++) {
final Thread t2 = new Thread(new Runnable() {
public void run() {
97
The Little Book of Semaphores – Threading Learning Tool
}
});
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();
98
The Little Book of Semaphores – Threading Learning Tool
}
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);
}
}
}
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;
99
The Little Book of Semaphores – Threading Learning Tool
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Multicar_Roller_Coaster(final JTextArea a) {
for (int k = 1; k <= m; k++) {
loadingArea[k] = new Semaphore(0);
unloadingArea[k] = new Semaphore(0);
}
loadingArea[1].release();
unloadingArea[1].release();
/* car thread creation */
ArrayList<Thread> car = new ArrayList<Thread>();
for (int i = 0; i < caramount; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
car(rollercoasterID());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
car.add(t1);
}
/* passenger thread creation */
ArrayList<Thread> passenger = new ArrayList<Thread>();
100
The Little Book of Semaphores – Threading Learning Tool
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 int next(int i) {
return (i + 1) % m;
}
public void car(int j) throws InterruptedException {
loadingArea[j].acquire();
logqueue.add("Car load(); \n");
boardQueue.release(C);
allAboard.acquire();
loadingArea[next(j)].release();
logqueue.add("Car run(); \n");
unloadingArea[j].acquire();
logqueue.add("Car unload(); \n");
101
The Little Book of Semaphores – Threading Learning Tool
logqueue.add("END");
unboardQueue.release(C);
allAshore.acquire();
unloadingArea[next(i)].release();
}
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);
}
}
public synchronized int rollercoasterID() {
if (i == m) {
i = 0;
}
i++;
return i;
}
102
The Little Book of Semaphores – Threading Learning Tool
}
Multiplex.java
package cases;
//add more threads*
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Multiplex {
int n = 1;
int i = 0;
int threadcount = 4;
String s1, s2, s3, s4;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Semaphore multi = new Semaphore(n);
public Multiplex(final JTextArea a) {
/* First thread creation */
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
execute(s1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
/* Second thread creation */
final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
execute(s2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
final Thread t3 = new Thread(new Runnable() {
public void run() {
try {
execute(s3);
} catch (InterruptedException e) {
103
The Little Book of Semaphores – Threading Learning Tool
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
final Thread t4 = new Thread(new Runnable() {
public void run() {
try {
execute(s4);
} 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();
}
}
});
/* Thread Identification */
s1 = t1.toString();
s2 = t2.toString();
s3 = t3.toString();
s4 = t4.toString();
/* Thread execution */
Log.start();
t1.start();
t2.start();
t3.start();
t4.start();
}
public void execute(String x) throws InterruptedException {
multi.acquire();
long execTime = System.nanoTime();
logqueue.add(x + " is in critical section\n");
logqueue.add(x + "Execution time =" +
Long.toString(System.nanoTime() - execTime) + "\n");
logqueue.add("END");
multi.release();
}
public void logger(JTextArea area) throws InterruptedException {
int endvalue = 0;
String output;
104
The Little Book of Semaphores – Threading Learning Tool
while (endvalue != threadcount) {
if (!logqueue.isEmpty()) {
output = (String) logqueue.poll();
if (output.equals("END")) {
endvalue++;
} else {
area.append(output);
}
}
Thread.sleep(50);
}
}
}
Multiplex_noSemaphore.java
package cases;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.swing.JTextArea;
public class Multiplex_noSemaphore {
int threadcount = 4;
int n = 1;
int i = 0;
String s1, s2, s3, s4;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Multiplex_noSemaphore(final JTextArea a) {
/* First thread creation */
final Thread t1 = new Thread(new Runnable() {
public void run() {
execute(s1);
}
});
/* Second thread creation */
final Thread t2 = new Thread(new Runnable() {
public void run() {
execute(s2);
}
});
final Thread t3 = new Thread(new Runnable() {
public void run() {
execute(s3);
}
});
105
The Little Book of Semaphores – Threading Learning Tool
final Thread t4 = new Thread(new Runnable() {
public void run() {
execute(s4);
}
});
/* 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();
}
}
});
/*
s1
s2
s3
s4
/*
Thread Identification */
= t1.toString();
= t2.toString();
= t3.toString();
= t4.toString();
Thread execution */
Log.start();
t1.start();
t2.start();
t3.start();
t4.start();
}
public void execute(String x) {
long execTime = System.nanoTime();
logqueue.add(x + " is in critical section\n");
logqueue.add(x + "Execution time = "
+ Long.toString(System.nanoTime() - execTime) +
"\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);
}
}
106
The Little Book of Semaphores – Threading Learning Tool
System.out.println("Log");
Thread.sleep(50);
}
System.out.println("End of Log");
}
}
Multiplex_synchronized_methods.java
package cases;
import javax.swing.JTextArea;
public class Multiplex_synchronized_methods {
int n = 1;
int i = 0;
String s1;
String s2;
public Multiplex_synchronized_methods(final JTextArea a){
/* First thread creation */
final Thread t1 = new Thread(new Runnable() {
public void run(){
long execTime1 = System.currentTimeMillis();
execute(a,s1);
execTime1 = System.currentTimeMillis() execTime1;
a.append("Thread 1 time = "+
Integer.toString((int) execTime1)+"\n");
}
});
/* Second thread creation */
final Thread t2 = new Thread(new Runnable() {
public void run(){
long execTime2 = System.currentTimeMillis();
execute(a,s2);
execTime2 = System.currentTimeMillis() execTime2;
a.append("Thread 2 time = "+
Integer.toString((int) execTime2)+"\n");
}
});
/*
s1
s2
/*
Thread Identification */
= t1.toString();
= t2.toString();
Thread execution */
t1.start();
t2.start();
107
The Little Book of Semaphores – Threading Learning Tool
}
public synchronized void execute(JTextArea area,String x){
area.append(x+ "\n");
i++;
i++;
area.append(Integer.toString(i)+ "\n");
i = i*2;
i++;
area.append(Integer.toString(i)+ "\n");
i--;
i = i +4;
area.append(Integer.toString(i)+ "\n");
}
}
Mutex.java
package cases;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Mutex {
public Semaphore mutex = new Semaphore(1);
int count = 0;
String s1,s2;
int threadcount = 2;
ConcurrentLinkedQueue<String> logqueue = new ConcurrentLinkedQueue<String>();
public Mutex(final JTextArea a){
/* First thread creation */
final Thread a1 = new Thread(new Runnable() {
public void run() {
try {
execute(s1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
/* Second thread creation */
final Thread b1 = new Thread(new Runnable() {
public void run() {
try {
execute(s1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
108
The Little Book of Semaphores – Threading Learning Tool
}
}
});
/* 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();
}
}
});
s1 = a1.toString();
s2 = b1.toString();
Log.start();
a1.start();
b1.start();
}
public void execute(String x) throws InterruptedException{
mutex.acquire();
long execTime = System.nanoTime();
logqueue.add(x + "has entered critical area \n");
count = count + 1;
logqueue.add("count = "+ count +"\n");
logqueue.add(x + "Execution time =" +
Long.toString(System.nanoTime() - execTime) + "\n");
logqueue.add("END");
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);
}
}
}
109
The Little Book of Semaphores – Threading Learning Tool
No_Starve_Mutex.java
package cases;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class No_Starve_Mutex {
int room1, room2 = 0;
Semaphore mutex = new Semaphore(1);
Semaphore t1 = new Semaphore(1);
Semaphore t2 = new Semaphore(0);
int threadcount = 10;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public No_Starve_Mutex(final JTextArea a) {
/*
* Thread creation - Creates 10 threads
*/
ArrayList<Thread> threader = new ArrayList<Thread>();
for (int i = 0; i < threadcount; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
solution();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
threader.add(t1);
}
/* Logging Thread */
final Thread Log = new Thread(new Runnable() {
public void run() {
try {
logger(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Log.start();
for (int i = 0; i < threadcount; i++) {
threader.get(i).start();
}
110
The Little Book of Semaphores – Threading Learning Tool
}
public void solution() throws InterruptedException {
logqueue.add("Thread start \n");
mutex.acquire();
room1 = room1 + 1;
mutex.release();
t1.acquire();
room2 = room2 + 1;
mutex.acquire();
room1 = room1 - 1;
if (room1 == 0) {
mutex.release();
t2.release();
} else {
mutex.release();
t1.release();
}
t2.acquire();
room2 = room2 - 1;
logqueue.add("Thread in critical section \n");
if (room2 == 0) {
t1.release();
} else {
t2.release();
}
logqueue.add("Thread end \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);
}
}
}
111
The Little Book of Semaphores – Threading Learning Tool
Producer_Consumer.java
package cases;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Producer_Consumer {
Semaphore mutex = new Semaphore(1);
Semaphore items = new Semaphore(0);
int threadcount = 15;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Producer_Consumer(final JTextArea a) {
/*
* Producers thread creation - Creates 5 producers
*/
ArrayList<Thread> producer = new ArrayList<Thread>();
for (int i = 0; i < 5; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
producer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
producer.add(t1);
}
/*
* Consumers thread creation - Creates 10 consumers
*/
ArrayList<Thread> consumer = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
consumer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
112
The Little Book of Semaphores – Threading Learning Tool
consumer.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 < 10; i++) {
consumer.get(i).start();
}
for (int i = 0; i < 5; i++) {
producer.get(i).start();
}
}
public void producer() throws InterruptedException {
int i = 0;
while (i != 2) {
waitForEvent();
mutex.acquire();
logqueue.add("Producer add event to buffer \n");
items.release();
mutex.release();
i = i + 1;
}
logqueue.add("END");
}
public void consumer() throws InterruptedException {
items.acquire();
mutex.acquire();
logqueue.add("Consumer get event \n");
mutex.release();
logqueue.add("Consumer process event \n");
logqueue.add("END");
}
/*
* will sleep for an amount of time and then awaken, this awakening we
will
* call the event
*/
public void waitForEvent() throws InterruptedException {
113
The Little Book of Semaphores – Threading Learning Tool
logqueue.add("Producer waiting for event \n");
Thread.sleep(1000);
logqueue.add("Producer event found \n");
}
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);
}
}
}
Queue.java
package cases;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Queue {
Semaphore leaderQueue = new Semaphore(0);
Semaphore followerQueue = new Semaphore(0);
int threadcount = 10;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Queue(final JTextArea a) {
/* leaders thread creation */
ArrayList<Thread> leaders = new ArrayList<Thread>();
for (int i = 0; i < threadcount/2; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
leader();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
114
The Little Book of Semaphores – Threading Learning Tool
}
});
leaders.add(t1);
}
ArrayList<Thread> followers = new ArrayList<Thread>();
for (int i = 0; i < threadcount/2; i++) {
final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
follower();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
followers.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++) {
leaders.get(i).start();
followers.get(i).start();
}
}
public void leader() throws InterruptedException {
followerQueue.release();
leaderQueue.acquire();
logqueue.add("Leader dance(); \n");
logqueue.add("END");
}
public void follower() throws InterruptedException {
leaderQueue.release();
followerQueue.acquire();
logqueue.add("Follower dance(); \n");
logqueue.add("END");
}
115
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
Reader_Writer.java
package cases;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Reader_Writer {
int readers = 0;
Semaphore mutex = new Semaphore(1);
Semaphore roomEmpty = new Semaphore(1);
int threadcount = 25;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Reader_Writer(final JTextArea a) {
/*
* Writers thread creation - Creates 5 writers
*/
ArrayList<Thread> writer = new ArrayList<Thread>();
for (int i = 0; i < 5; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
writer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
116
The Little Book of Semaphores – Threading Learning Tool
writer.add(t1);
}
/*
* Readers thread creation - Creates 20 readers
*/
ArrayList<Thread> reader = new ArrayList<Thread>();
for (int i = 0; i < 20; i++) {
final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
reader();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
reader.add(t2);
}
/* Logging Thread */
final Thread Log = new Thread(new Runnable() {
public void run() {
try {
logger(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Log.start();
int j = 0;
for (int i = 0; i < 5;i++) {
writer.get(i).start();
while(j<20){
reader.get(j).start();
if(j == 3){
break;
}
if(j == 7){
break;
}
if(j == 11){
break;
}
if(j == 15){
break;
}
if(j == 19){
break;
}
j++;
}
117
The Little Book of Semaphores – Threading Learning Tool
j++;
}
}
public void writer() throws InterruptedException {
roomEmpty.acquire();
logqueue.add("Writer in critical section \n");
roomEmpty.release();
logqueue.add("Writer exits critical section \n");
logqueue.add("END");
}
public void reader() throws InterruptedException {
mutex.acquire();
readers = readers + 1;
logqueue.add("Reader has entered room \n");
if (readers == 1) {
roomEmpty.acquire(); /* first in locks */
logqueue.add("Reader first in locks room \n");
}
mutex.release();
logqueue.add("Reader enters critical section \n");
mutex.acquire();
readers = readers - 1;
if (readers == 0) {
roomEmpty.release(); /* last out unlocks */
logqueue.add("Reader last out unlocks room \n");
}
mutex.release();
logqueue.add("Reader has left \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);
}
}
}
118
The Little Book of Semaphores – Threading Learning Tool
Rendezvous.java
package cases;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Rendezvous {
final Semaphore aArrived = new Semaphore(0);
final Semaphore bArrived = new Semaphore(0);
int threadcount = 2;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Rendezvous(final JTextArea a) {
/* First thread creation */
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
rendezvous1();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
/* Second thread creation */
final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
rendezvous2();
} 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();
119
The Little Book of Semaphores – Threading Learning Tool
t1.start();
t2.start();
}
public void rendezvous1() throws InterruptedException {
logqueue.add("Statement a1 \n");
aArrived.release();
bArrived.acquire();
logqueue.add("Statement a2 \n");
logqueue.add("END");
}
public void rendezvous2() throws InterruptedException {
logqueue.add("Statement b1 \n");
bArrived.release();
aArrived.acquire();
logqueue.add("Statement b2 \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);
}
}
}
Reusable_Barrier.java
package cases;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class Reusable_Barrier {
final Semaphore aArrived = new Semaphore(0);
final Semaphore bArrived = new Semaphore(0);
final Semaphore mutex = new Semaphore(1);
final Semaphore turnstile = new Semaphore(0);
final Semaphore turnstile2 = new Semaphore(1);
120
The Little Book of Semaphores – Threading Learning Tool
int count = 0;
int n = 4; // number of threads
int threadcount = n;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Reusable_Barrier(final JTextArea a) {
/* Threadgroup1 creation */
ArrayList<Thread> threadgroup1 = new ArrayList<Thread>();
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<Thread> threadgroup2 = new ArrayList<Thread>();
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();
}
}
});
121
The Little Book of Semaphores – Threading Learning Tool
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){
turnstile2.acquire(); /* lock the second */
turnstile.release(); /* unlock the first */
}
mutex.release();
turnstile.acquire();
turnstile.release();
/* first turnstile */
/* critical point */
mutex.acquire();
count = count - 1;
if(count == 0){
turnstile.acquire(); /* lock the first */
turnstile2.release(); /* unlock the second */
}
mutex.release();
turnstile2.acquire();
turnstile2.release();
logqueue.add("END");
}
/* second turnstile */
public void logger(JTextArea area) throws InterruptedException {
int endvalue = 0;
String output;
122
The Little Book of Semaphores – Threading Learning Tool
while (endvalue != threadcount) {
if (!logqueue.isEmpty()) {
output = (String) logqueue.poll();
if (output.equals("END")) {
endvalue++;
} else {
area.append(output);
}
}
Thread.sleep(50);
}
}
}
River_Crossing.java
package cases;
import
import
import
import
import
java.util.ArrayList;
java.util.concurrent.BrokenBarrierException;
java.util.concurrent.ConcurrentLinkedQueue;
java.util.concurrent.CyclicBarrier;
java.util.concurrent.Semaphore;
import javax.swing.JTextArea;
public class River_Crossing {
CyclicBarrier barrier = new CyclicBarrier(4);
Semaphore mutex = new Semaphore(1);
int hackers = 0;
int serfs = 0;
Semaphore hackerQueue = new Semaphore(0);
Semaphore serfQueue = new Semaphore(0);
int threadcount = 40;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public River_Crossing(final JTextArea a) {
/* hacker thread creation */
ArrayList<Thread> hacker = new ArrayList<Thread>();
for (int i = 0; i < threadcount/2; i++) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
try {
Hackers();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
123
The Little Book of Semaphores – Threading Learning Tool
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
hacker.add(t1);
}
/* serf thread creation */
ArrayList<Thread> serf = new ArrayList<Thread>();
for (int i = 0; i < threadcount/2; i++) {
final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
Serfs();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
serf.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 < threadcount/2; k++) {
hacker.get(k).start();
serf.get(k).start();
}
}
public void Hackers() throws InterruptedException,
BrokenBarrierException {
boolean isCaptain = false;
124
The Little Book of Semaphores – Threading Learning Tool
mutex.acquire();
hackers = hackers + 1;
if (hackers == 4) {
hackerQueue.release(4);
hackers = 0;
isCaptain = true;
}
else if (hackers == 2 && serfs >= 2) {
hackerQueue.release(2);
serfQueue.release(2);
serfs = serfs - 2;
hackers = 0;
isCaptain = true;
}
else {
mutex.release(); /* captain keeps the mutex */
}
hackerQueue.acquire();
logqueue.add("Hacker board(); \n");
barrier.await();
if (isCaptain) {
logqueue.add("Hacker Captain rowBoat(); \n");
mutex.release(); /* captain releases the mutex */
}
logqueue.add("END");
}
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.acquire();
logqueue.add("Serf board(); \n");
barrier.await();
if (isCaptain) {
125
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
}
Roller_Coaster.java
package cases;
import
import
import
import
java.util.ArrayList;
java.util.concurrent.ConcurrentLinkedQueue;
java.util.concurrent.Semaphore;
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
Semaphore
Semaphore
Semaphore
boardQueue = new Semaphore(0);
unboardQueue = new Semaphore(0);
allAboard = new Semaphore(0);
allAshore = new Semaphore(0);
int caramount = 10;
int passengeramount = caramount * C;
int threadcount = caramount + passengeramount;
ConcurrentLinkedQueue<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Roller_Coaster(final JTextArea a) {
/* car thread creation */
ArrayList<Thread> car = new ArrayList<Thread>();
126
The Little Book of Semaphores – Threading Learning Tool
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<Thread> passenger = new ArrayList<Thread>();
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();
127
The Little Book of Semaphores – Threading Learning Tool
}
}
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);
}
128
The Little Book of Semaphores – Threading Learning Tool
}
}
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
public Sushi_Bar(final JTextArea a) {
execute(a);
}
public void execute(final JTextArea a){
/* Patron thread creation */
ArrayList<Thread> patron = new ArrayList<Thread>();
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() {
129
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
130
The Little Book of Semaphores – Threading Learning Tool
Thread.sleep(50);
}
}
}
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<String> logqueue = new
ConcurrentLinkedQueue<String>();
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<Thread> philosophers = new ArrayList<Thread>();
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 */
131
The Little Book of Semaphores – Threading Learning Tool
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();
}
132
The Little Book of Semaphores – Threading Learning Tool
}
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;
}
}
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();
133
The Little Book of Semaphores – Threading Learning Tool
}
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();
}
}
Drivers
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;
134
The Little Book of Semaphores – Threading Learning Tool
import
import
import
import
import
import
import
import
import
javax.swing.JButton;
javax.swing.JComboBox;
javax.swing.JFrame;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.JPanel;
javax.swing.JScrollPane;
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);
135
The Little Book of Semaphores – Threading Learning Tool
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);
}
});
136
The Little Book of Semaphores – Threading Learning Tool
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);
137
The Little Book of Semaphores – Threading Learning Tool
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");
138
The Little Book of Semaphores – Threading Learning Tool
@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;
}
}
139
The Little Book of Semaphores – Threading Learning Tool
}
}
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");
140
The Little Book of Semaphores – Threading Learning Tool
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);
}
}
SaveDriver.java
package drivers;
import
import
import
import
import
import
java.awt.Dimension;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.io.BufferedWriter;
java.io.FileWriter;
import
import
import
import
import
import
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
javax.swing.JTextArea;
javax.swing.JTextField;
141
The Little Book of Semaphores – Threading Learning Tool
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());
}
}
});
142
The Little Book of Semaphores – Threading Learning Tool
}
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());
}
}
});
}
}
SingleDriver.java
package drivers;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.Dimension;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.ItemEvent;
java.awt.event.ItemListener;
javax.swing.JButton;
javax.swing.JComboBox;
javax.swing.JFrame;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.JPanel;
javax.swing.JScrollPane;
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",
143
The Little Book of Semaphores – Threading Learning Tool
"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();
}
});
144
The Little Book of Semaphores – Threading Learning Tool
/* 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");
145
The Little Book of Semaphores – Threading Learning Tool
@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;
}
146
The Little Book of Semaphores – Threading Learning Tool
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")
147
The Little Book of Semaphores – Threading Learning Tool
Tanenbaums_Solution tanenbaum = new Tanenbaums_Solution(a);
break;
}
}
}
}
PURE
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(); */
}
}
148
The Little Book of Semaphores – Threading Learning Tool
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);
149
The Little Book of Semaphores – Threading Learning Tool
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 */
}
}
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 */
150
The Little Book of Semaphores – Threading Learning Tool
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 */
}
}
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();
151
The Little Book of Semaphores – Threading Learning Tool
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();
}
}
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 */
152
The Little Book of Semaphores – Threading Learning Tool
}
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 */
}
}
}
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 {
153
The Little Book of Semaphores – Threading Learning Tool
mutex.acquire();
waiting = waiting + 1;
mutex.release();
bus.acquire();
/* board(); */
boarded.release();
}
}
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();
}
154
The Little Book of Semaphores – Threading Learning Tool
public void SmokerWithPaper() throws InterruptedException{
tobacco.acquire();
match.acquire();
agentSem.release();
}
}
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; i<5; i++){
fork[i] = new Semaphore(1);
}
/*Implementation code */
}
public int left(int i){
return i;
}
public int right(int i){
return (i+1)%5;
}
public void get_forks(int i) throws InterruptedException{
footman.acquire();
fork[right(i)].acquire();
fork[left(i)].acquire();
}
public void put_forks(int i){
fork[right(i)].release();
fork[left(i)].release();
footman.release();
}
}
Dining_Savages.java
package PURE;
import java.util.concurrent.Semaphore;
public class Dining_Savages {
int servings = 0;
int M = 5; /*needed to be added */
Semaphore mutex = new Semaphore(1);
155
The Little Book of Semaphores – Threading Learning Tool
Semaphore emptyPot = new Semaphore(0);
Semaphore fullPot = new Semaphore(0);
public void cook() throws InterruptedException{
while (true){
emptyPot.acquire();
/* putServingsInPot(M); */
fullPot.release();
}
}
public void savages() throws InterruptedException{
while (true){
mutex.acquire();
if (servings == 0){
emptyPot.release();
fullPot.acquire();
servings = M;
}
servings = servings - 1;
/* getServingFromPot(); */
mutex.release();
/* eat(); */
}
}
}
Exclusive_Queue.java
package PURE;
import java.util.concurrent.Semaphore;
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);
public void leaders() throws InterruptedException{
mutex.acquire();
if (followers >0){
followers = followers - 1;
followerQueue.release();
}
else{
leaders = leaders + 1;
mutex.release();
leaderQueue.acquire();
}
/* dance(); */
rendezvous.acquire();
156
The Little Book of Semaphores – Threading Learning Tool
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();
}
}
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 <= (3*(adults - 1)) && children <= (3*(adults - 1))){
leaving = leaving - 1;
adults = adults - 1;
adultQueue.release();
}
mutex.release();
}
157
The Little Book of Semaphores – Threading Learning Tool
public void adult() throws InterruptedException{
mutex.acquire();
adults = adults + 1;
if(waiting > 0){
int n = Math.min(3, waiting);
childQueue.release(n);
waiting = waiting - n;
children = children + n;
}
mutex.release();
/* critical section */
mutex.acquire();
if(children <= (3*(adults - 1))){
adults = adults - 1;
mutex.release();
}
else{
leaving = leaving + 1;
mutex.release();
adultQueue.acquire();
}
}
}
Faneuil_Hall.java
package PURE;
import java.util.concurrent.Semaphore;
public class Faneuil_Hall {
Semaphore noJudge = new Semaphore(1);
int entered = 0;
int checked = 0;
int judge = 0;
Semaphore mutex = new Semaphore(1);
Semaphore confirmed = new Semaphore(0);
Semaphore allSignedIn = new Semaphore(1);
public void immigrant() throws InterruptedException{
noJudge.acquire();
/* enter(); */
entered = entered + 1;
noJudge.release();
mutex.acquire();
/* checkIn(); */
checked = checked + 1;
if(judge == 1 && entered == checked){
allSignedIn.release(); /* and pass the mutex */
}
158
The Little Book of Semaphores – Threading Learning Tool
else{
mutex.release();
}
/* sitDown(); */
confirmed.acquire();
/* swear(); */
/* getCertificate(); */
noJudge.acquire();
/* leave(); */
noJudge.release();
}
public void judge() throws InterruptedException{
noJudge.acquire();
mutex.acquire();
/* enter(); */
judge = 1;
if(entered > checked){
mutex.release();
allSignedIn.acquire(); /* and get the mutex back */
}
/* confirm(); */
confirmed.release(checked);
entered = checked = 0;
/* leave(); */
judge = 0;
mutex.release();
noJudge.release();
}
public void spectator() throws InterruptedException{
noJudge.acquire();
/* enter(); */
noJudge.release();
/* spectate(); */
/* leave(); */
}
}
159
The Little Book of Semaphores – Threading Learning Tool
Lightswitch.java
package PURE;
import java.util.concurrent.Semaphore;
public class Lightswitch {
int counter = 0;
Semaphore mutex = new Semaphore(1);
Semaphore semaphore = new Semaphore(1);
public void lock() throws InterruptedException{
mutex.acquire();
counter = counter + 1;
if (counter == 1){
semaphore.acquire();
}
mutex.release();
}
public void unlock() throws InterruptedException{
mutex.wait();
counter = counter - 1;
if(counter == 0){
semaphore.release();
}
mutex.release();
}
}
Modus_Hall.java
package PURE;
import java.util.concurrent.Semaphore;
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);
public void heathen() throws InterruptedException {
heathenTurn.acquire();
heathenTurn.release();
mutex.acquire();
heathens = heathens + 1;
if(status.equals("neutral")){
status = "heathens rule";
mutex.release();
160
The Little Book of Semaphores – Threading Learning Tool
}
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();
}
}
Multicar_Roller_Coaster.java
package PURE;
/*
*
*
*
*
*
161
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
The Little Book of Semaphores – Threading Learning Tool
* 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<m; k++){
loadingArea[k] = new Semaphore(0);
unloadingArea[k] = new Semaphore(0);
}
loadingArea[1].release();
unloadingArea[1].release();
}
public int next(int i){
return (i + 1) % m;
}
public void car() throws InterruptedException{
mutexcarnumber.acquire();
int j = i;
i = i + 1;
mutexcarnumber.release();
loadingArea[j].acquire();
/* load(); */
boardQueue.release(C);
allAboard.acquire();
loadingArea[next(j)].release();
/* run() */
unloadingArea[j].acquire();
/* unload() */
unboardQueue.release(C);
allAshore.acquire();
unloadingArea[next(i)].release();
162
The Little Book of Semaphores – Threading Learning Tool
}
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();
}
}
Multiplex.java
package PURE;
import java.util.concurrent.Semaphore;
public class Multiplex {
int n = 2;
public Semaphore multi = new Semaphore(n);
public void run() throws InterruptedException{
multi.acquire();
// critical section
multi.release();
}
}
Mutex.java
package PURE;
import java.util.concurrent.Semaphore;
public class Mutex {
public Semaphore mutex = new Semaphore(1);
int count = 0;
163
The Little Book of Semaphores – Threading Learning Tool
public void run() throws InterruptedException{
mutex.acquire();
// critical section
count = count + 1;
mutex.release();
}
}
No_Starve_Mutex.java
package PURE;
import java.util.concurrent.Semaphore;
public class No_Starve_Mutex {
int room1, room2 = 0;
Semaphore mutex = new Semaphore(1);
Semaphore t1 = new Semaphore(1);
Semaphore t2 = new Semaphore(0);
public void solution() throws InterruptedException {
mutex.acquire();
room1 = room1 + 1;
mutex.release();
t1.acquire();
room2 = room2 + 1;
mutex.acquire();
room1 = room1 - 1;
if (room1 == 0) {
mutex.release();
t2.release();
} else {
mutex.release();
t1.release();
}
t2.acquire();
room2 = room2 - 1;
/* critical section */
if (room2 == 0) {
t1.release();
} else {
t2.release();
}
}
}
164
The Little Book of Semaphores – Threading Learning Tool
Producer_Consumer.java
package PURE;
import java.util.concurrent.Semaphore;
public class Producer_Consumer {
Semaphore mutex = new Semaphore(1);
Semaphore items = new Semaphore(0);
public void producer() throws InterruptedException {
waitForEvent();
mutex.acquire();
/* buffer.add(event); */
items.release();
mutex.release();
}
public void consumer() throws InterruptedException {
items.acquire();
mutex.acquire();
/* event = buffer.get(); */
mutex.release();
/* event.process(); */
}
/*
* will sleep for an amount of time and then awaken, this awakening we
will
* call the event
*/
public void waitForEvent() throws InterruptedException {
/* waiting for event */
Thread.sleep(1000);
}
}
Queue.java
package PURE;
import java.util.concurrent.Semaphore;
public class Queue {
Semaphore leaderQueue = new Semaphore(0);
Semaphore followerQueue = new Semaphore(0);
public void leader() throws InterruptedException{
followerQueue.release();
leaderQueue.acquire();
/* dance(); */
}
165
The Little Book of Semaphores – Threading Learning Tool
public void follower() throws InterruptedException{
leaderQueue.release();
followerQueue.acquire();
/* dance(); */
}
}
Reader_Writer.java
package PURE;
import java.util.concurrent.Semaphore;
public class Reader_Writer {
int readers = 0;
Semaphore mutex = new Semaphore(1);
Semaphore roomEmpty = new Semaphore(1);
public void writer() throws InterruptedException{
roomEmpty.acquire();
/* critical section for writers */
roomEmpty.release();
}
public void reader() throws InterruptedException{
mutex.acquire();
readers = readers + 1;
if(readers == 1){
roomEmpty.acquire();
/* first in locks */
}
mutex.release();
/* critical section for readers */
mutex.acquire();
readers = readers - 1;
if(readers == 0){
roomEmpty.release();
}
mutex.release();
/* last out unlocks */
}
}
Rendezvous
package PURE;
import java.util.concurrent.Semaphore;
public class Rendezvous {
final Semaphore aArrived = new Semaphore(0);
final Semaphore bArrived = new Semaphore(0);
166
The Little Book of Semaphores – Threading Learning Tool
public void execute1()throws InterruptedException{
/* statement a1 */
aArrived.release();
bArrived.acquire();
/* statement a2 */
}
public void execute2() throws InterruptedException{
/* statement b1 */
bArrived.release();
aArrived.acquire();
/* statement b2 */
}
}
Rendezvous_Deadlock.java
package PURE;
import java.util.concurrent.Semaphore;
public class Rendezvous_Deadlock {
final Semaphore aArrived = new Semaphore(0);
final Semaphore bArrived = new Semaphore(0);
public void execute1()throws InterruptedException{
/* statement a1 */
bArrived.acquire();
aArrived.release();
/* statement a2 */
}
public void execute2() throws InterruptedException{
/* statment b1 */
aArrived.acquire();
bArrived.release();
/* statement b2 */
}
}
Reusable_Barrier.java
package PURE;
import java.util.concurrent.Semaphore;
public class Reusable_Barrier {
final Semaphore aArrived = new Semaphore(0);
final Semaphore bArrived = new Semaphore(0);
final Semaphore mutex = new Semaphore(1);
final Semaphore turnstile = new Semaphore(0);
final Semaphore turnstile2 = new Semaphore(1);
167
The Little Book of Semaphores – Threading Learning Tool
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){
turnstile2.acquire(); /* lock the second */
turnstile.release(); /* unlock the first */
}
mutex.release();
turnstile.acquire();
turnstile.release();
/* first turnstile */
/* critical point */
mutex.acquire();
count = count - 1;
if(count == 0){
turnstile.acquire(); /* lock the first */
turnstile2.release(); /* unlock the second */
}
mutex.release();
turnstile2.acquire();
turnstile2.release();
}
}
168
/* second turnstile */
The Little Book of Semaphores – Threading Learning Tool
River_Crossing.java
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;
public class River_Crossing {
CyclicBarrier barrier = new CyclicBarrier(4);
Semaphore mutex = new Semaphore(1);
int hackers = 0;
int serfs = 0;
Semaphore hackerQueue = new Semaphore(0);
Semaphore serfQueue = new Semaphore(0);
public void Hackers() throws InterruptedException,
BrokenBarrierException {
boolean isCaptain = false;
mutex.acquire();
hackers = hackers + 1;
if(hackers == 4){
hackerQueue.release(4);
hackers = 0;
isCaptain = true;
}
else if(hackers == 2 && serfs >= 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){
169
The Little Book of Semaphores – Threading Learning Tool
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 */
}
}
}
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
Semaphore
Semaphore
Semaphore
boardQueue = new Semaphore(0);
unboardQueue = new Semaphore(0);
allAboard = new Semaphore(0);
allAshore = new Semaphore(0);
public void car() throws InterruptedException{
/* load(); */
boardQueue.release(C);
allAboard.acquire();
/* run(); */
/* unload(); */
unboardQueue.release(C);
170
The Little Book of Semaphores – Threading Learning Tool
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();
}
}
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 */
171
The Little Book of Semaphores – Threading Learning Tool
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();
}
}
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();
172
The Little Book of Semaphores – Threading Learning Tool
}
}
}
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<5; i++){
state[i] = "thinking";
sem[i] = new Semaphore(0);
}
/*Implementation code */
}
public int left(int i){
return i;
}
public int right(int i){
return (i+1)%5;
}
public void get_fork(int i) throws InterruptedException{
mutex.acquire();
state[i] = "hungry";
test(i);
mutex.release();
sem[i].acquire();
}
public void put_fork(int i) throws InterruptedException{
mutex.acquire();
state[i] = "thinking";
test(right(i));
test(left(i));
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();
}
}
}
173
The Little Book of Semaphores – Threading Learning Tool
The_Room_Party.java
package PURE;
import java.util.concurrent.Semaphore;
public class The_Room_Party {
int students = 0;
String dean = "not here";
Semaphore mutex = new Semaphore(1);
Semaphore turn = new Semaphore(1);
Semaphore clear = new Semaphore(0);
Semaphore lieIn = new Semaphore(0);
public void dean() throws InterruptedException {
mutex.acquire();
if (students > 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 */
174
The Little Book of Semaphores – Threading Learning Tool
}
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();
}
}
}
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;
175
The Little Book of Semaphores – Threading Learning Tool
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();
}
}
176
The Little Book of Semaphores – Threading Learning Tool
Chapter 8 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. (http://dictionary.reference.com/browse/semaphore)
177
Chapter 9 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
178
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