What is Slipped Condition in Multi-threading?

Slipped Condition is a special type of race condition that can occur in a multithreaded application. In this, a thread is suspended after reading a condition and before performing the activities related to it. It rarely occurs, however, one must look for it if the outcome is not as expected.

Example: Suppose there are two thread A and thread B which want to process a string S. Firstly, thread A is started, it checks if there are any more characters left to process, initially the whole string is available for processing, so the condition is true. Now, thread A is suspended and thread B starts. It again checks the condition, which evaluates to true and then processes the whole string S. Now, when thread A again starts execution, the string S is completely processed by this time and hence an error occurs. This is known as a slipped condition.

Program to demonstrate slipped conditions in Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to demonstrate
// slipped conditions
  
public class Main {
    public static void main(String[] args)
    {
        ReadingThread readingThread
            = new ReadingThread();
        SlippedThread slippedThread
            = new SlippedThread();
  
        slippedThread.start();
        readingThread.start();
    }
}
  
class CommonResource {
    static final String string = "Hello";
    static int pointerPosition = 0;
}
  
// Thread to demonstrate a slipped condition
class SlippedThread extends Thread {
    @Override
    public void run()
    {
        // Check if any characters
        // are left to process
        if (CommonResource.pointerPosition
            != CommonResource.string.length()) {
            System.out.println("Characters left! "
                               + "I can process the string");
  
            // Cause the thread to wait to cause
            // a slipped condition
            try {
                synchronized (this)
                {
                    wait(500);
                }
            }
  
            catch (InterruptedException e) {
                System.out.println(e);
            }
  
            try {
                while (CommonResource.pointerPosition
                       < CommonResource.string.length()) {
  
                    System.out.println("Thread1 "
                                       + CommonResource.string
                                             .charAt(
                                                 CommonResource
                                                     .pointerPosition));
                    CommonResource.pointerPosition++;
                }
            }
  
            catch (StringIndexOutOfBoundsException e) {
                System.out.println("\nNo more character left"
                                   + " to process. This is a"
                                   + " slipped condition");
            }
        }
    }
}
  
// Thread to process the whole String
class ReadingThread extends Thread {
    @Override
    public void run()
    {
        System.out.println("Thread2 trying to "
                           + "process the string");
        while (CommonResource.pointerPosition
               < CommonResource.string.length()) {
  
            System.out.print("Thread2 "
                             + CommonResource.string
                                   .charAt(
                                       CommonResource
                                           .pointerPosition));
            CommonResource.pointerPosition++;
        }
    }
}

chevron_right


Output:

Characters left! I can process the string
Thread2 trying to process the string
Thread2 H
Thread2 e
Thread2 l
Thread2 l
Thread2 o
No more character left to process. This is a slipped condition

The solution to the problem of Slipped Conditions is fairly simple and straightforward. Any resources that a thread is going to access after checking the condition, must be locked by the thread and should only be released after the work is performed by the thread. All the access must be synchronized.

With respect to the problem above, the slipped conditions can be eliminated, by locking the String object of the CommonResource class. In this scenario, the thread first gains the access and locks the String and then tries to process the String.

Solution to the above example

filter_none

edit
close

play_arrow

link
brightness_4
code

public class Main {
    public static void main(String[] args)
    {
        ReadingThread readingThread
            = new ReadingThread();
        SlippedThread slippedThread
            = new SlippedThread();
  
        slippedThread.start();
        readingThread.start();
    }
}
  
class CommonResource {
  
    static final String string = "Hello";
    static int pointerPosition = 0;
  
    // A static variable added
    // to lock the String object
    static boolean isLocked = false;
}
  
// Thread to demonstrate a slipped condition
class SlippedThread extends Thread {
    @Override
    public void run()
    {
        // Check if any characters
        // are left to process
        if (CommonResource.isLocked
                != true
            && CommonResource.pointerPosition
                   != CommonResource.string.length()) {
  
            System.out.println("Characters left! "
                               + "I can process the string");
            CommonResource.isLocked = true;
  
            // Cause the thread to wait to cause
            // a slipped condition
            try {
                synchronized (this)
                {
                    wait(250);
                }
            }
  
            catch (InterruptedException e) {
                System.out.println(e);
            }
  
            try {
                while (CommonResource.pointerPosition
                       < CommonResource.string.length()) {
  
                    System.out.println("Thread1 "
                                       + CommonResource
                                             .string.charAt(
                                                 CommonResource
                                                     .pointerPosition));
                    CommonResource.pointerPosition++;
                }
            }
  
            catch (StringIndexOutOfBoundsException e) {
                System.out.println("\nNo more character "
                                   + "left to process. This is "
                                   + "a slipped condition");
            }
            CommonResource.isLocked = false;
        }
    }
}
  
// Thread to process the whole String
class ReadingThread extends Thread {
    @Override
    public void run()
    {
        System.out.println("Thread2 trying to"
                           + " process the string");
        if (CommonResource.isLocked == false) {
            CommonResource.isLocked = true;
            synchronized (this)
            {
                while (CommonResource.pointerPosition
                       < CommonResource.string.length()) {
                    System.out.println("Thread2 "
                                       + CommonResource.string
                                             .charAt(
                                                 CommonResource
                                                     .pointerPosition));
                    CommonResource.pointerPosition++;
                }
            }
        }
        CommonResource.isLocked = false;
    }
}

chevron_right


Output

Characters left! I can process the string
Thread2 trying to process the string
Thread1 H
Thread1 e
Thread1 l
Thread1 l
Thread1 o

In the above program, a new static boolean member isLocked is added to the CommonResource class. Now, whenever a thread tries to process the string, it first obtains the lock and then processes it. In this example, the SlippedCondition thread checks whether the isLocked is false and there is string left to be processed. If it is, it obtains the lock and then waits and finally processes the string. Meanwhile, the ReadingThread tries to process the string but it can’t as isLocked was set true by the SlippedThread.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.