Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading problem using System.out.print vs println

I have the following thread which simply prints a dot every 200ms:

public class Progress {

    private static boolean threadCanRun = true;
    private static Thread progressThread = new Thread(new Runnable() 
    {
        public void run() {
            while (threadCanRun) {
                System.out.print('.');
                System.out.flush();
                try {
                    progressThread.sleep(200);
                } catch (InterruptedException ex) {}
            }
        }
    });

    public static void stop()
    {
        threadCanRun = false;
        progressThread.interrupt();
    }

    public static void start()
    {
        if (!progressThread.isAlive())
        {
            progressThread.start();
        } else
        {
            threadCanRun = true;
        }
    }

}

I start the thread with this code (for now):

 System.out.println("Working.");
 Progress.start();


 try {
        Thread.sleep(10000); //To be replaced with code that does work.
 } catch (InterruptedException ex) {}

 Progress.stop();

What's really strange is this:

If I use System.out.println('.'); , the code works exactly as expected. (Apart from the fact that I don't want a new line each time).

With System.out.print('.');, the code waits for ten seconds, and then shows the output.

System.out.println:

     Print dot, wait 200ms, print dot, wait 200ms etc...

System.out.print:

     Wait 5000ms, Print all dots

What is happening, and what can I do to go around this behaviour?

EDIT:

I have also tried this:

private static synchronized void printDot()
{
    System.err.print('.');
}

and printDot() instead of System.out.print('.'); It still doesn't work.

EDIT2:

Interesting. This code works as expected:

        System.out.print('.');
        System.out.flush();  //Makes no difference with or without
        System.out.println();

This doesn't:

        System.err.print('.');
        System.err.flush();
        System.out.print('.');
        System.out.flush();

Solution: The issue was netbeans related. It worked fine when I run it as a jar file from java -jar.

This is one of the most frustrating errors I have seen in my life. When I try to run this code with breakpoints in debug mode, everything works correctly.

like image 934
David Avatar asked Sep 26 '11 11:09

David


People also ask

Is it safe to use printf in multithreaded programs?

the standard C printf() and scanf() functions use stdio so they are thread-safe.

Why we should not use System out Println?

out. println is an IO-operation and therefor is time consuming. The Problem with using it in your code is, that your program will wait until the println has finished.

Is Println thread safe?

println(String) is thread safe. Anyone's opinion and experience are very welcomed. the method AReallyLongTrickMethod() will be called, and will return, before System.


1 Answers

The stdout is line buffered. Use stderr, or flush the PrintStream after each print.

like image 88
Ingo Avatar answered Oct 20 '22 17:10

Ingo