I used multithreading to improve performance, ensuring thread safety with mutexes like ImageMutex and PixelMutex to prevent shared resource access conflicts. To synchronize threads, I utilized condition variables. For instance, a resizing operation waits until all processing tasks are complete before beginning
Furthermore, I implemented task-based parallelism with a custom Farm class. This class enqueues tasks and distributes them across multiple threads, handling load balancing effectively. The combination of mutexes and this task-based approach made the program both scalable and robust.



