Click here to Skip to main content
15,886,806 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I want to know the sequence of the execution between the threads including the main thread.

Maybe take an example:
Java
import java.util.concurrent.TimeUnit;

public class Resource1 {

    public void f() {
        // other operations should not be locked... 
        System.out.println(Thread.currentThread().getName()
                + ":not synchronized in f()");
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()
                        + ":synchronized in f()");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void g() {
        // other operations should not be locked... 
        System.out.println(Thread.currentThread().getName()
                + ":not synchronized in g()");
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()
                        + ":synchronized in g()");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void h() {
        // other operations should not be locked... 
        System.out.println(Thread.currentThread().getName()
                + ":not synchronized in h()");
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()
                        + ":synchronized in h()");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        final Resource1 rs = new Resource1();

        new Thread() {
            public void run() {
                rs.f();
            }
        }.start();

        new Thread() {
            public void run() {
                rs.g();
            }
        }.start();

        rs.h();
    }
}

Q1: How is the execution order of Thread-0 , Thread-1 and main thread ?
(Actually, the code does not assign the names for the threads. "Thread-0" and "Thread-1" are the printout result of the code above, so I just use them as their names. Of course, "Thread-0" is the first created thread by main thread.)

Firstly, main thread runs. Then it creates Thread-0 and run its .start() (ie running rs.f() ). Then CPU focus on the Thread-0.
Until the code "TimeUnit.SECONDS.sleep(3);" (inside rs.f() ) is encountered, the thread-0 sleeps and keeps the object key, but it pass the right of use of CPU back to main thread.
And main thread (current thread) creates another thread ie thread-1 and calls the run() of Thread-1.

Now, the next executing thread would be Thread-0 or Thread-1?

The reason for Thread-0:
As, there are 3 threads: main thread, Thread-0 and Thread-1. The execution order looks alike as below: (the order is from LHS to RHS, it is due to the creation order of each thread)

Round 1 Main Thread-0 Thread-1
Round 2 Main Thread-0 Thread-1
Round 3 Main Thread-0 Thread-1

So, the next one is thread-0 since Main thread is the immediate previous currently active thread.

The reason for Thread-1:
Since main thread calls thread-1 .start(), the rs.g() runs actually.


In fact, which one is the right answer?


Q2
Let's jump to rs.g() , no matter what the right answer of Q1 is.

Thread-1 runs the statement right before the synchronized block, then runs the synchronized block. At the time, it finds the instance object key is held by someone else(it should be Thread-0). So it pauses the execution here and pass the right of use of CPU to the next one.

But which is the next one, Main thread or thread-0?


Q3
I learnt online that when one of the threads releases the object key of the synchronized block, there is no rule to predict which thread could get the key next time.
However, just focus on the execution order of the threads in each iteration of the CPU time.

In the above example, main thread is created first, followed by Thread-0 and Thread-1.
Is that the execution order of the threads in each iteration of the CPU time should be
Main --> Thread-0 --> Thread-1 ??

Q4
besides, how to ask the thread to do something each time it is being active thread and fails to get the instance object key of the synchronized block?
Posted

1 solution

The order of execution between threads, if you are not adding specific constraints using thread synchronization primitives, is uncertain and, in practice, really varies in different executions of the application. The use of any assumptions on any certain order in software development makes the application invalid (unless it is designed intentionally to demonstrate the effects of randomness of the order of execution). This is a know problems called "incorrect dependency on the order of execution", or, more widespread term, "race condition": http://en.wikipedia.org/wiki/Race_condition[^].

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900