Is a scanner in java thread safe?

I am interested in using java.util.Scanner

. I was reading the docs and saw a line saying that the scanner is unsafe for multithreading use without external synchronization. Can I confirm that this means that two separate Scanner objects in two separate threads running in two separate files can interfere with each other?

Can anyone help me synchronize the scanner object externally to use for thread safe operation?

+3


source to share


4 answers


If you are using the same Scanner instance in two threads, you will run into problems if you do not synchronize access to the object. But two separate copies of the scanner will never interfere with each other.

change the response when asked how to sync

First, are you really sure you need to sync at all? You can safely use different scanner instances on different threads without any danger. One thread can have
Scanner s1 = new Scanner (new File ("/tmp/file1.txt");


and another thread can have
Scanner s2 - new Scanner (new File ("/tmp/file2.txt"));


and there is no risk. Different scanners can use the same file, different files, or completely different data sources. However, you still need to be careful. As noted by Stephen C below , you will still run into corruption if two separate scanner instances use the same stream or reader as their input, then they will steal characters from each other.This warning applies to constructors using InputStream , Readable, and ReadableByteChannel.

The problem with using one scanner across multiple threads is that it consumes characters sequentially from the same source. If you have multiple threads consuming these characters in an unsynchronized fashion, each thread will receive some of the characters, and none of the threads will receive all of the characters. To illustrate: imagine you have a scanner reading the string "qwertyuiop" and two separate threads of each call function next()

at the same time, then one thread can see "ertip" and the other thread will receive "qwyuo"; which would be useless.



My suggestions for syncing:

  • Not multithreading! Even amputation of body parts is preferred to make the multi-threaded application stable, scalable and flexible!
  • Sometimes you can subclass the class, not related to the stream (or encapsulated and delegated), and synchronize calls to the base class (or delegate) synchronised (this) { super.next (); }

    . But don't try it with the Scanner! There are so many consumer methods out there and you have no idea how the class is internally implemented, so you are doomed to fail! See Proposition 1.
  • What I would try to do here is one thread running the scanner and feeding the tokens to the ArrayBlockingQueue. This way you will get full tokens entering the queue in the correct order. You can have as many threads as you want to read from the queue. But keep in mind that any of your threads can be blocked for both reading and writing of this queue if you don't deal with full and empty conditions. Chances are that no matter what you do, you will end up with dangling threads that never run out. See point 1. It gets more complicated if you want to sometimes call different following methods (eg nextInt()

    , nextDouble()

    ) or use has methods (eg hasNextInt()

    , hasNextDouble()

    ), but not as hard as point 2.

Finally, I would suggest that you see point 1.

+2


source


I want to raise this question in the accepted answer.

If you are using the same Scanner instance in two threads, you will run into problems if you do not synchronize access to the object. But two separate copies of the scanner will never interfere with each other.



Actually, two separate instances Scanner

can interfere with each other if they have the same input source. If you have two Scanner objects wrapping System.in

used by two separate threads. When you call hasNextInt()

on one Scanner

, it will read further from System.in

enough characters to determine that a valid integer exists. If the first thread did not call then nextInt()

, the second thread would not be able to read the characters read. They will sit in the internal buffers of the first Scanner

.

Essentially, one scanner prevents another from "stealing" characters. The presence of two scanners in one stream is pathological. Your statement is only true for two scanners on different input streams.

+1


source


Multithreading refers to two threads working on the same object. Two threads running on two different sites are fine.

0


source


You can use multiple scanners using different data sources from multiple streams without issue.

Using one scanner with multiple threads will lead to problems.

0


source







All Articles