Monitors provide a solution to particular access problems not handled easily by mutexes. For example, you might want many threads to be able to simultaneously read data, but only one thread to be able write data. While the thread writes data, you might want to block read access by other threads.
A monitor is used by a critical section to declare what type of data access the critical section will be performing on the protected data; that is, reading, writing, or browsing.
The monitor synchronization facility can be extended to provide a critical section for browsing; this can be very useful in real world applications. A browser reads data and, depending on conditions you have set, might or might not write to protected data items. While a browser is active, any number of critical sections that simply read the data are allowed, while any other critical sections that browse or write are not allowed. If the browser thread determines that it needs to write to the protected data, it requests a conversion of the browse lock to a write lock. The conversion process waits until all critical sections that read the data are finished, and then bars any other critical sections that read or write data from accessing the data. The browser proceeds to write with exclusive access to the protected data items (whose state is guaranteed to be the same as it was when the browser was just reading the protected data).
Example
The following example code shows a monitor that controls the access of multiple threads that count items in, or add items to, a table. The code:
Working-Storage Section. 78 table-length value 20. 01 table-monitor usage monitor-pointer. 01 table-current pic x(4) comp-x value 0. 01 table-1. 05 table-item-1 pic x(10) occurs table-length. Local-Storage Section. 01 table-count pic x(4) comp-x. 01 table-i pic x(4) comp-x. . . . *> Initialization code, executed while in single *> threaded mode move 0 to table-current open table-monitor * Add an item to table-1, this is a writer critical section set table-monitor to writing if table-current < table-length add 1 to table-current move 'filled in' to table-item-1(table-current) end-if set table-monitor to not writing * Count items in table-1, this is a reader critical section set table-monitor to reading move 0 to table-count perform varying table-i from 1 by 1 until table-i > table-current if table-item-1 (table-i) = 'filled in' add 1 to table-count end-if end-perform set table-monitor to not reading
Example
The following is an example of a browser critical section:
Working-Storage Section. 01 data-monitor usage monitor-pointer. 01 data-value pic x(4) comp-x value 0. * Initialization code, executed while in single threaded * mode open data-monitor * Add an item to table-1, this is a browser critical section set data-monitor to browsing if data-value < 20 set data-monitor to writing converting from browsing add 5 to data-value set data-monitor to not writing else set data-monitor to not browsing end-if
We do not recommend that you use a browse lock for such a simple check. Usually, you need only use a browser if a significant amount of work has to be done to determine if a write lock is actually required, and you want to maximize multi-threading throughout your application. There are various other monitor conversions available to help you maximize the level of multi-threading in your application