Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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