Wiki
Version 4 (modified by Charles, 13 years ago)

--

lock

Specify a code block to execute after obtaining a lock on the object of an expression.

The code block constitutes a critical section that only one thread may execute at a time.

This construct ensures that one thread does not enter a critical section of code while another thread is in the critical section gated by the same locked object.
If another thread attempts to enter a locked block, it will wait, blocking until the lock on the object is released.

Grammar

lock <expression> 
    <block>

Platform

On .Net this acts the same as the  C# lock statement

Examples

# Critical section is to generate output through a single shared writer fm multiple threads
class Tester
    var _statusWriter as Writer?
...
    cue init
    ...
        _statusWriter = MyWriter()
        # gen and setup multiple threads with .runInThread as the thread code to run
    ...
    
    def runInThread
        while true
            ...
            lock _statusWriter
                _statusWriter.writeLine(statusLine)
            
# This is the example from the C# lock doc page converted to cobra
use System.Threading

class Account
    var _thisLock  = Object()  # is private
    var balance as int
    var r = Random()

    cue init(initial as int) is public
        base.init
        .balance = initial

    def withdraw(amount as int) as int
        # This condition will never be true unless the lock statement
        # is commented out:
        if .balance < 0
            throw Exception("Negative Balance")

        # Comment out the next line to see the effect of leaving out 
        # the lock keyword:
        lock _thisLock
            if .balance >= amount
                print "Balance before Withdrawal :  ", .balance
                print "Amount to Withdraw        : -" , amount
                .balance = .balance - amount
                print "Balance after Withdrawal  :  ", .balance
                return amount
            else
                return 0 # transaction rejected

    def doTransactions is public
        for i in 0 : 100
            .withdraw(.r.next(1, 100))

class Test
    def main is shared
        threads = Thread[](10)
        acc = Account(1000)
        for i in 0 : 10
            t = Thread(ThreadStart(ref acc.doTransactions))
            threads[i] = t
        for i in 0 : 10
            threads[i].start

See Also