This document discusses concurrency and threading in Java and Haskell. It covers: 1) Threads allow concurrent programs to perform multiple tasks simultaneously through time-slicing, though execution is not truly simultaneous. 2) Java threads can be created by extending Thread or implementing Runnable. Haskell uses forkIO to spawn concurrent threads. 3) Shared memory access requires synchronization to prevent race conditions. Solutions include locking (synchronized in Java), STM transactions in Haskell.