更新时间:2023-01-10 14:41:58
如果在两个线程中使用相同的Scanner实例,则除非您同步对该对象的访问,否则将遇到麻烦.但是,两个单独的Scanner实例将永远不会相互干扰.
If you use the same instance of Scanner in two threads you will have trouble unless you synchronise access to the object. But two separate instances of Scanner will never interfere with each other.
编辑以回复询问如何同步的评论
首先,您真的确定需要完全同步吗?您可以安全地在不同线程中使用不同的扫描仪实例,而不会造成任何危险.一个线程可以有Scanner s1 = new Scanner (new File ("/tmp/file1.txt");
而另一个线程可以具有Scanner s2 - new Scanner (new File ("/tmp/file2.txt"));
而且没有风险.不同的扫描仪可以使用相同的文件,不同的文件或完全不同的数据源.不过,您仍然需要保持谨慎.正如Stephen C 下面所指出的,如果两个单独的Scanner实例使用与他们的输入,然后他们将互相窃取字符.此警告适用于使用InputStream,Readable和ReadableByteChannel的构造方法.
First, are you really sure you need to synchronise at all? You can safely use different scanner instances in different threads without any danger. One thread can haveScanner s1 = new Scanner (new File ("/tmp/file1.txt");
and another thread can haveScanner s2 - new Scanner (new File ("/tmp/file2.txt"));
and there is no risk. The different scanners can use the same file, different files or completely different data sources. You still need to be cautious though. As noted by Stephen C below you will still get broken operation if two separate instances of Scanner are using the same stream or reader as their input then they will steal characters from each other. This warning applies to the constructors using InputStream, Readable and ReadableByteChannel.
在多个线程中使用单个扫描仪的问题在于,它顺序消耗了单个来源的字符.如果您有多个线程以不同步的方式使用这些字符,则每个线程将获得一些字符,而没有一个线程将获得所有字符.举例说明:假设您有一个扫描程序读取字符串"qwertyuiop",并且有两个单独的线程,每个线程同时调用函数next()
,那么一个线程可能会看到"ertip",而另一个线程将得到"qwyuo";这将是无用的.
The problem with using a single scanner in multiple threads is that it is sequentially consuming characters from a single source. If you have multiple threads consuming these characters in unsynchronised fashion then each thread will get some of the characters and none of the threads will get all of the characters. To illustrate: Imagine you have a scanner reading the string "qwertyuiop", and two separate threads each call function next()
at the same time, then one thread might see "ertip" and the other thread would get "qwyuo"; which would be useless.
我对此进行同步的建议是:
My suggestions to synchronise this are:
synchronised (this) { super.next (); }
.但是请不要使用Scanner尝试此操作!消费者方法太多了,您不知道该类是如何在内部实现的,所以注定要失败!请参阅建议1.nextInt()
,nextDouble()
)或使用 has 方法(例如hasNextDouble()
),但不如第2点那么复杂.synchronised (this) { super.next (); }
. But don't try this with Scanner! There are so many consumer methods, and you have no idea how the class is implemented internally so you are doomed to fail! See suggestion 1.nextInt()
, nextDouble()
) or use the has methods (e.g. hasNextInt()
, hasNextDouble()
), but not as complicated as point 2.最后,我建议您看一下第1点.
Finally, I would suggest you see point 1.