The following illustrates a simple implementation of a FIFO queue which can be safely accessed concurrently:

 define Queue as process { [int] items }

 int Queue::get():
     item = items[0]
     this.items = items[1..]
     return item

 void Queue::put(int item):
     this.items = items + [item]

Instances of Queue are processes containing lists of ints.  Two methods, get and put, are provided for manipulating them.  Methods are distinguished from functions in Whiley by the R::m() syntax, where R is the type of the receiver, and m the message name.

To create a Queue process we use a spawn expression, as follows:

 void ::main(System.Console console):
     queue = spawn { items: [] }

In some ways, spawn is similar to new from object-oriented languages like Java. The key difference is that, unlike an object, a process represents a distinct thread of execution.

Finally, we can interact with a Queue process by sending messages either synchronously or asynchronously.  The following illustrates a complete example:

 void ::main(System.Console console):
     queue = spawn { items: [] }
     item = queue.get()
     out.println(str(item)) // prints "1"

Here, the statement queue!put(1) sends the message put(1) asynchronously to the process referred to by queue.  Since the message send is asynchronous, the sender will not block in most cases (i.e. provided the receivers mailbox still has space). In contrast, the statement item = queue.get() uses a synchronous message send in order to access value returned. A synchronous message send blocks the sender until the receiver has processed the message.