We have already introduced the concept of a thread as a unit of computation that can be scheduled. During design, the principal trade-off concerns the number of threads. Increasing the number of threads can simplify certain algorithms and techniques but increases the risk of sequencing problems. Reducing the number of threads reduces sequencing problems but makes the software more rigid and often more inefficient. SynchronizationWhen two or more threads must access the same memory location, a mechanism is needed to prevent the two threads from interfering with each other. Two threads may try to execute a method that modifies a data value at the same time. Some languages, such as Java, provide a language keyword that automatically adds the mechanism to prevent this simultaneous access. Others, such as C++, require explicit structures that each individual developer must construct. Synchronization can be easier in an object-oriented language because the mechanism can be localized on the modifier method for the common data attribute. The actual data is protected from direct access by more than a single specific method. Specifying the Need for SynchronizationIn design documents, synchronization can be specified in the guard clauses of the UML state diagram. In Java, the keyword synchronize is used on the signature of a method to specify the need for a synchronization mechanism. C++ has no keywords for specifying synchronization; however, the synchronization mechanisms are designed as classes. The creation of an instance of a monitor object, for instance, indicates the location at which synchronization is needed. Testing That the Need Is MetEven though the language automatically provides the mechanism, the developer may have misplaced the specification for synchronization. During class testing, a test harness should create multiple thread-based test objects. Each of these fires a request against the object under test (OUT). |