There may be times when you want to be sure that a group of operations is performed without switching threads. For example, if you have a utility paragraph that does a series of math operations on a data item, you will not want to begin that paragraph and then switch to another thread if another thread uses that data item. In this case, you can use the LOCK THREAD statement to ensure that a series of operations are all accomplished together. For example:
PARA-1. LOCK THREAD ADD DATA-1 TO DATA-2 IF DATA-2 > DATA-2-DIV-LIMIT MOVE DATA-2-DIV-LIMIT TO DATA-2 COMPUTE DATA-2 = DATA-2 / DATA-3 UNLOCK THREAD.
The LOCK THREAD statement ensures that no other thread executes. This condition remains in effect until the thread is unlocked (with UNLOCK THREAD) or the thread terminates. In the preceding example, if the LOCK THREAD was omitted, another thread referencing DATA-2 could see its value after the ADD but before the COMPUTE. This could be a value that is not meaningful.
A thread can have more than one lock. Each time a LOCK THREAD statement executes in the thread, the number of locks held by that thread increases by one. To allow other threads to run again, an equal number of UNLOCK THREAD statements must also execute. Each UNLOCK THREAD statement removes the last lock applied to the thread. This capability allows a thread to lock itself, call a subroutine that also locks itself, and remain locked after that subroutines unlocks itself.
The data sharing aspect of threads is very powerful. However, ensuring that the data are always consistent can be a difficult programming problem. When writing multithreaded programs, you should strive to share data in a well-defined manner to minimize this problem. The best way to do this is to share as little data as possible and to be clear when each thread is allowed to use that data.