In the following set of exercises, you are required to implement higher-level concurrency abstractions in terms of basic JVM concurrency primitives. Some of these exercises introduce concurrent counterparts of sequential programming abstractions, and, in doing so, highlight important differences between sequential and concurrent programming. The exercises are not ordered in any particular order, but some of them rely on specific content from earlier exercises or this chapter.

Implement a

`parallel`

method, which takes two computation blocks`a`

and`b`

, and starts each of them in a new thread. The method must return a tuple with the result values of both the computations. It should have the following signature:def parallel[A, B](a: =>A, b: =>B): (A, B)

Implement a

`periodically`

method, which takes a time interval`duration`

specified in milliseconds, and a computation block`b`

. The method starts a thread that executes the computation block`b`

every`duration`

milliseconds. It should...