Print in Order
Published: 2022-09-24 22:46:26

**Challenge**
Suppose we have a class:

```
public class Foo {
  public void first() { print("first"); }
  public void second() { print("second"); }
  public void third() { print("third"); }
}
```
The same instance of Foo will be passed to three different threads. Thread A will call first(), thread B will call second(), and thread C will call third(). Design a mechanism and modify the program to ensure that second() is executed after first(), and third() is executed after second().

Note:

We do not know how the threads will be scheduled in the operating system, even though the numbers in the input seem to imply the ordering. The input format you see is mainly to ensure our tests' comprehensiveness.

**Let's Understand the challenge**

What an Instance and a Thread?
An object is an instance of a class. In the example below, phone is a class while instance of phone is phone_one. Therefore to create an instance of foo would be to create an object. 

```
class Phone:
    def __init__(self):
        self.brand = "samsung"
        self.model = "A50 
        self.color = "blue"

#object 
phone_one = Phone()
```
A thread is a set of operations that would be operated at different time sequence. It allow's one perform different actions at different time sequence instead of the order of execution.
let's say you have to wait for an input to complete action one, you can move to the next available action, action two while you await action one.

```
import threading
import time

def eat(food):
    print("preparing to eat",food)
    time.sleep(1)
    print("back to eating ",food)

def movie(movie):
    print("watching", movie)
    print("Done watching")


x = threading.Thread(target=eat, args=("rice",))
x.start()

y = threading.Thread(target=movie, args=("spiderman",))
y.start()

```

what you expected as output

```
preparing to eat rice
back to eating  rice
watching spiderman
Done watching

```
Actual output

```
preparing to eat rice
watching spiderman
Done watching
back to eating  rice
```

If you observe the flow while running eat function, we out of the eat function to the movie function before the final  execution of eat and this is because we encoutered a delay in eat function

So to solve this challenge i used a lock object that thread provides. when we have two or more threads access a shared piece of data is called race condition. which is the case in this challenge. Having the same instance of foo pass to the three different threads. 

To solve a race condition, a common method is to used the Lock object that thread  provides. Lock allows one thread to run at a time until the lock is released before next thread runs 

```
import threading
from threading import Lock

class Number:
    def __init__(self):
        self.lock_one = threading.Lock()
        self.lock_two = threading.Lock()
        self.lock_one.acquire()
        self.lock_two.acquire()
        
    def first(self, num) -> None:
        print("one", num)
        self.lock_one.release()


    def second(self, num) -> None:
        self.lock_one.acquire()
        print("two", num)
        self.lock_two.release()


    def third(self,num) -> None:
        self.lock_two.acquire()
        print("three", num)
        
  #object      
num_instance = Number()
    
thread_a = threading.Thread(target=num_instance.third, args=(1,))
thread_a.start()
    
thread_b = threading.Thread(target=num_instance.second, args=(2,))
thread_b.start()
    
thread_c = threading.Thread(target=num_instance.first, args=(3,))
thread_c.start()
    
```
OUTPUT

```
one 3
two 2
three 1
```

BONUS