Difference in thread execution in Java

Asked

Viewed 342 times

6

See the execution of two similar programs in Java. One inherits from Thread and another implements the interface Runnable:

Program1:

public class PingPong extends Thread{
private String msg;
private int delay;

PingPong(String s,int tempo){
    msg = s;
    delay = tempo;
}

public void run(){
    try{
        for (int i=1;i<=10;i++){
            System.out.println(msg+ " " + i);
            Thread.sleep(delay);
        }
    }
    catch (Exception e){
        System.err.println("Deu pau!");
        return;
    }
}

public static void main(String[] args) {
    PingPong ping = new PingPong("ping",500);
    ping.start();

    PingPong pong = new PingPong("pong",1000);
    pong.start();

    System.out.println("*** FIM DO PROGRAMA PRINCIPAL ***");
}}

It generates the following output:

execuçâo

And we have program 2:

    public class PingPong2 implements Runnable{
    private String msg;
    private int delay;

    PingPong2(String s,int tempo){
        msg = s;
        delay = tempo;
    }

    public void run(){
        try{
            for (int i=1;i<=10;i++){
                System.out.println(msg+ " " + i);
                Thread.sleep(delay);
            }
        }
        catch (Exception e){
            System.err.println("Deu pau!");
            return;
        }
    }

    public static void main(String[] args) {
        Runnable ping = new PingPong2("ping",500);
        Runnable pong = new PingPong2("pong",1000);

        new Thread(ping).start();
        new Thread(pong).start();
        System.out.println("*** FIM DO PROGRAMA PRINCIPAL ***");
    }
}  

Generating the following output:

execuçâo

Why the output on program1 is not printed "ping1" since in the method implementation run(), the print on the screen is made before placing the thread to sleep (on hold)?

  • Did the answer solve your problem? Do you think you can accept it? If you don’t know how you do it, check out [tour]. This would help a lot to indicate that the solution was useful to you and to give an indication that there was a satisfactory solution. You can also vote on any question or answer you find useful on the entire site.

1 answer

5

First: the class of the first example is conceptually wrong. PingPong is not a Thread, so you shouldn’t inherit it from it. It works, but it’s wrong. That’s not really the problem. I understand that this is just a test, but it is common for people to transpose things like this into normal code. So it is worth the alert.

Threads are complicated, are unpredictable, the programmer has little control over them. They are two separate and independent lines of execution, so there is no guarantee of execution order. Threads tend to create racing conditions.

It depends on the scheduling of the operating system. Especially the first execution can give a bigger difference because the creation of a new thread is something costly.

What probably occurred is that the execution of pong took a more favorable schedule and managed to complete the creation of the thread and its beginning before. Most likely the creation of the thread of ping started before, but what matters is the conclusion.

The second example could have occurred the same, just got "lucky" not to occur. Each execution will be different. Note that it also does not perform as expected and intercalates the ping with the pong in the first executions as if the delay were the same.

Do not use threads if you need predictability. They are less useful than people realize.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.