How to sych out and err streams in Java [duplicate] - java

This question already has answers here:
Java + Eclipse: Synchronize stdout and stderr
(5 answers)
Closed 8 years ago.
In the code below how can I make number printer in black and red in order we expect, like below:
1 (black)
1 (red)
2 (black)
2 (red)
as opposed to what it actually does(some random order depending on whether the err or out streams are available):
1 (black)
2 (black)
1 (red)
2 (red)
code:
package threads;
public class CThread implements Runnable
{
#Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 20; i++) {
outt(i);
err(i);
}
}
synchronized public void outt(int i){
System.out.println(i);
}
synchronized public void err(int i){
System.err.println(i);
}
public static void main(String [] org){
Thread th = new Thread(new CThread());
th.start();
}
}

Even if you try to synchronize the writing of your Streams (System.out and System.err in that case), it does not prevent that the program which is watching those Streams (Eclipse in your case) is reading those streams in that order.
There is a lot of infrastructure between that (including the OS which can sort those IO operations in whatever order it wants).
For real world applications the answer to this kind of problem is to use a logging framework. With those you can write all messages of all levels to the same file (usually in a separate thread, in the order they where logged).
If you do not want to use a logging framework and want to rely on System.out / System.err, then you cannot reliably control on how this output is being read by 3rd party applications. The only thing you can do, is to synchronize the writing of those streams by synchronizing (and flushing) the IO operations with a common lock object.
Be aware however that this technique then is a severe bottleneck to any multithreaded code.

Create an ArrayList for output and error. Instead of System.out and System.err append to that list. Then decide when you like to print it and first print an empty the output list, the print and empty the error list. The has to be synchronized. Also: New output and error coming after the ignition of the printing will not be sorted in - of course - and this cannot be solved since the output to System.out and System.err is merged in the console first come first served. If you like to solve this you have to wait until the program finishes, then print all output and all error.

Related

Does Thread.sleep have no effect in Stream processing? [duplicate]

This question already has answers here:
Intermediate stream operations not evaluated on count
(3 answers)
Closed last month.
The following program is from OCP Study Guide by Jeanne Boyarsky and Scott Selikoff:
import java.util.*;
class WhaleDataCalculator {
public int processRecord(int input) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// Handle interrupted exception
}
return input + 1;
}
public void processAllData(List<Integer> data) {
data.stream().map(a -> processRecord(a)).count();
}
public static void main(String[] args) {
WhaleDataCalculator calculator = new WhaleDataCalculator();
// Define the data
List<Integer> data = new ArrayList<Integer>();
for (int i = 0; i < 4000; i++)
data.add(i);
// Process the data
long start = System.currentTimeMillis();
calculator.processAllData(data);
double time = (System.currentTimeMillis() - start) / 1000.0;
// Report results
System.out.println("\nTasks completed in: " + time + " seconds");
}
}
The authors claim
Given that there are 4,000 records, and each record takes 10
milliseconds to process, by using a serial stream(), the results will
take approximately 40 seconds to complete this task.
However, when I am running this in my system, it is taking between 0.006 seconds to 0.009 seconds on every run.
Where is the discrepancy?
That's because of the use of count, which performs a trick in later Java versions.
Since you're only interested in the number of elements, count will try to get the size directly from the source, and will skip most other operations. This is possible because you are only doing a map and not, for example, a filter, so the number of elements will not change.
If you add peek(System.out::println), you'll see no output as well.
If you call forEach instead of count, running the code will probably take 40 seconds.
Since Java 9 operation count() has been optimized in such so that if during the initialization of the stream (when stages of the pipeline are being chained) it turns out that there are no operations which can change the number of elements in the stream source allows evaluating the number of elements it contains, then count() does not trigger the execution of the pipeline, but instead asks the source "how many of these guys do you have?" and immediately returns the value.
So while running processAllData() a Stream instance would be constructed and right after that the method would terminate, because none of the elements would be actually processed.
Here's a quote from the documentation:
API Note:
An implementation may choose to not execute the stream pipeline
(either sequentially or in parallel) if it is capable of computing the
count directly from the stream source. In such cases no source
elements will be traversed and no intermediate operations will be
evaluated. Behavioral parameters with side-effects, which are strongly
discouraged except for harmless cases such as debugging, may be
affected.For example, consider the following stream:
List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count();
The number of elements covered by the stream source, a List, is known
and the intermediate operation, peek, does not inject into or remove
elements from the stream (as may be the case for flatMap or filter
operations). Thus the count is the size of the List and there is no
need to execute the pipeline and, as a side-effect, print out the list
elements.
And by the way, besides the trick behind this test, this case doesn't require the usage of Stream API. Since the value returned by count() is ignored and everything that is need is to fire a side-effect on each element of the list, then Iterable.forEach() can be used instead:
public void processAllData(List<Integer> data) {
data.forEach(a -> processRecord(a));
}
The call of .map(a -> processRecord(a)) did not run at all, the reason is because you are running this program with a JDK version more than 1.8.
Let's take this example to make it easy to understand:
long number = Stream.of("x", "x", "x").map(e -> {
System.out.println("Hello");
return e;
}).count();
System.out.println(number);
Try to run it using a JDK 1.8 , after that run it using a JDK 11.
In java 8, count() acts as a terminal operation, all the intermediate operations(map method here) will be executed, the map operation will be executed and will print the hello message. you will get this output:
Hello
Hello
Hello
3
In greater than 1.8 Java versions, 11 as example here, Java can determine the number of elements of the stream directly, if there is no intermediate operation that can change the number of the elements of the stream (example : filter() ), no intermediate method will be executed, just the count method will be executed, so you will not see any hello message but the number of the element of this stream will be calculated and you can use it. your output will be like that:
3
If you like to see the hello message in the Java versions greater than 1.8, you should add an intermediate operation to your stream pipeline that can change the number of element of the stream, let's add the filter method to the pipeline and see the output on java 11:
long number = Stream.of("x", "x", "x").map(e -> {
System.out.println("Hello");
return e;
}).filter(element-> element.equals("x")).count();
System.out.println(number);
Here the output:
Hello
Hello
Hello
3

Why Exception log changes printed place with same code? [duplicate]

This question already has answers here:
System.out.println and System.err.println out of order
(7 answers)
Closed 9 years ago.
Please consider this java code:
public class CMain {
public static void main(String[] args){
for (int i = 0; i < 10; i++) {
System.out.println("A");
System.err.println("B");
}
}
}
By a quick look at the code, some of us may think the output has to be the print of As and Bs alternatively. However is not! It is a random appearance of 10 A characters and 10 B ones. Something like this:
Why is that? and what is the solution for it so that the As and Bs gets displayed alternatively ( A B A B A B ...)
Before I ask this question, I checked several other similar questions for solution and non worked for my case! I have brought some of them here:
Synchronization and System.out.println
Java: synchronizing standard out and standard error
Java: System.out.println and System.err.println out of order
PS. I am using Eclipse as my IDE
Why does this happen?
This is because out and err are two different output streams. However, both of them print on console. So you do not see them as different streams. Moreover, when you do out.println(), it is not guaranteed that you will see the output on the console as soon as the statement gets executed. Instead, the strings are usually(depends on the system) stored in an output buffer (if you will) which is processed later by the system to put the output from the buffer onto the screen.
Solution :(
Although, as Eng.Fouad pointed out that you can use setOut(System.err) or setErr(System.out) to make them ordered, I would still not suggest doing that when you are actually putting this in an application (only use it for debugging purposes).
What the proposed solution does is that it will end up using only one stream for both the standard output and the standard error, which I do not think is a good thing to do.
They are different OutputStreams. If you really need to guarantee the order of printing them, use:
System.setErr(System.out);
or
System.setOut(System.err);
Since there are two separate streams, the output you are giving is possible.

Why don't threads run consistently?

I am playing around with multithreading and came across an inconsistency when running a small snippet of code. The following code should print out 123123... but what I'm getting is
class RunnableDemo implements Runnable {
private String message;
RunnableDemo(String m) {
message = m;
}
public void run() {
try {
for (int i = 0; i < message.length(); i++) {
System.out.print(message.charAt(i));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
new Thread(new RunnableDemo("1111111")).start();
new Thread(new RunnableDemo("2222222")).start();
new Thread(new RunnableDemo("3333333")).start();
}
}
Output: 123231231132123231321
Output: 123213123123213213213
Output: 123231213213231231213
What I don't get is that it run correctly the first pass through (prints '123') but then the second pass through it prints '231'. If the thread is printing a char, sleeping 1 second, then repeating. Shouldn't the pattern 123123... be consistent each time I run the code or at least follow the pattern of the first 3 chars?
The following code should print out 123123
Not necessarily. You should basically never rely on threads with no synchronization between them happening to wake up and execute in any particular order.
Let's take the very first character output: there's no guarantee that that will be 1. Yes, you're starting the thread printing 1 first, but that doesn't mean that's the first thread that will actually start executing run first - or even if it does, that doesn't mean that's the first thread that will get as far as the System.out.print call.
Given the fairly long sleep, I would expect (but ideally not rely on) the output being a sequence of 7 "chunks", where each "chunk" consists of the characters "123" in some permutation. But if you've got three threads which all go to sleep for a second at "roughly" the same time, you shouldn't expect them to necessarily wake up in the order 1, 2, 3 - and again, even if they do, one of them may pre-empt another within the loop body.
On a really, really slow machine, even that expectation would be invalid - imagine it takes a random amount of time between 0 and 20 seconds to call charAt - unlikely, but it's a feasible thought experiment. At that point, one of the threads could race ahead and finish its output before another of the threads managed to print anything.
Threads are designed to be independent - if you want them to work in a coordinated fashion, you have to specify that coordination yourself. There are plenty of tools for the job, but don't expect it to happen magically.
You can't predict what piece of program CPU runs at a time. While running some process the CPU converts the process into small pieces of work. As multiple processes are running at a time. CPU has to schedule according to scheduling algorithm implemented. So, in short, you cannot predict what CPU does next unless you programmatically synchronize the pieces of code.

How can I make my for loop execute tasks completely before going on to the next iteration? [duplicate]

This question already has answers here:
System.out.println and System.err.println out of order
(7 answers)
Closed 8 years ago.
I am trying to parse a file at work but for some reason my for loop does not execute an entire iteration of tasks before going on to the next iteration.
I have a sample code here that shows the same issue and I think that if I can fix this simple example I will be able to fix my more complex issue at work.
Sample code :
package loops;
public class Loops {
public static void main(String[] args) {
System.out.println("here goes");
for(int i=0;i<1000;i++){
System.err.println(i);
if(i==i){
System.out.println(i+1);
}
}
}}
The above code runs and prints the iteration of the loop "i" in red. It goes through the if statement and prints the i+1 in black. My issue is that instead of being red black red black it finishes the if statements long before it finishes the for loop "i" printouts. Is there any way to make this loop go in order? I have tried to make it sleep after each iteration but that does not fix it.
Thanks.
This because both System.out and System.err could be buffered streams. This means that writes are not executed right when data is placed onto the stream but rather in chunks.
Try to flush the output right after each print:
System.out.println(...);
System.out.flush();
In this way you will force the stream to flush their buffer before executing other instructions. This may come with a performance cost.
Stdout is buffered, stderr isn't. Print both to stdout or both to stderr, don't mix them.

Exception output not coming in sequence

My code is as follows:
public class BoxingUnboxingExample {
public static void main(String[] args) {
Integer i1 = null;
Integer i3 = 10;
BoxingUnboxingExample b = new BoxingUnboxingExample();
b.go(i3);
b.go(i1);
}
private void go(int a){
System.out.println("a");
}
}
Now my question is:
Sometimes I get the following error message,
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
a
Whereas, I think It should always be the following,
a
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
Am I correct?
One reason could be the exception stack trace uses standard error (System.err) to output the error data while System.out.println uses standard output (System.out).
That means both are using different mechanisms to output the data, these may not be properly synchronized.
You can also refer this earlier question.
ex
If you are in Eclipse, this is a known problem, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205
Output and Error are two different streams System.err and System.out.
Read this:
It is acceptable—and normal—for standard output and standard error to
be directed to the same destination, such as the text terminal.
Messages appear in the same order as the program writes them, unless
buffering is involved. (For example, a common situation is when the
standard error stream is unbuffered but the standard output stream is
line-buffered; in this case, text written to standard error later may
appear on the terminal earlier, if the standard output stream's buffer
is not yet full.)
from wikipeda
so your output stream (System.out.println) is actually buffered. Internally it calles the BufferedWriter.write() methode. take alook at this:
How System.out.println() really works
There are at least 2 effects at play here, both related to how System.out and System.err are (naturally) 2 different streams.
Buffering
System.err and System.out are both PrintStreams, which are buffered by default, however System.err is usually set to auto-flush after every write (of a byte array or whenever a newline is written).
As such, if System.err is flushed before System.out is flushed, it will appear on screen first.
The reading of those streams
In editors, it is not uncommon for both System.out and System.err to be displayed within a single console. The way this happens will influence the order in which they are displayed. Eclipse has 2 processes, one for every stream, to read from the streams and display them. The order in which they will read (and as such, display) is non-deterministic. The process that reads from System.err would have a 50% chance of being the first to receive input if both streams are written to quasi-simultanously. As such, they may appear to be randomly interleaved.
public class Main {
public static void main(String[] args) {
System.setErr(System.out); // this line seems to solve the problem
System.out.println("test");
throw new RuntimeException("Test");
}
}

Categories