Testing is key to the process of verifying the correctness of a multithreaded program.
Test your multithreaded program by having multiple instances of the program active at the same time. If your application allows the number of threads to vary, configure each instance of the program with a different number of threads.
Test your multithreaded program by running it repeatedly with a different mix of applications running. The interaction of different applications might reveal timing problems or race conditions.
Environments running stressful workload can reveal contention, timing, and performance problems.
Whenever possible, run your multithreaded program on different hardware models with varying workload and stress levels. Different hardware models, especially multiprocessor systems, reveal a variety of problems. If you are porting an application from another platform, verify that your application produces the same result on both platforms.
It is typically sufficient to test a single-threaded program on one hardware model and expect that it will behave identically on different hardware models. Unlike with single-threaded programs, you cannot have the same expectation with a multithreaded program that runs on a hardware platform that supports kernel threads. On these platforms, each thread runs in a separately dispatched task. Depending on processor speed, main memory sizes, storage capacity, and other hardware characteristics, timing problems or race conditions might result when the multithreaded programs are called on different hardware. Multiprocessor systems further increase the likelihood of discovering potential problems. On multiprocessor systems, two different threads can be running the same sequence of code at the same time.
A problem for Java application developers is the implementation of the Java virtual machine (JVM). On some platforms, the JVM is single-threaded. On i5/OS™, the JVM is multithreaded. Similar problems might occur with a Java application as with an application from another platform that supports user threads.
If you are porting an application from another platform, you need to know the threads model that the other platform supported. If the platform supported a user threads model, you might encounter problems with the application on i5/OS because it supports a kernel threads model. A key difference between the two models is that the user threads model uses cooperative scheduling and the kernel threads model uses preemptive scheduling. With a user threads model, only one thread in the application can be active at a given time. With a kernel threads model, the machine determines which threads are eligible to run. Race conditions, resource contention, and other problems might occur with kernel threads because the application writer did not consider these potential problems when using user threads.