java中的扫描器不是线程安全的吗?

java中的扫描器不是线程安全的吗?,java,thread-safety,java.util.scanner,Java,Thread Safety,Java.util.scanner,我对使用java.util.Scanner感兴趣。我正在阅读,看到一行字说,如果没有外部同步,扫描仪对于多线程使用是不安全的。我能否确认这意味着在两个单独的线程中的两个单独的扫描仪对象在两个单独的文件上运行时可能会相互干扰 有人能帮我从外部同步扫描仪对象,以便进行安全的线程操作吗?多线程使用是指在同一对象上运行的两个线程。两个线程在两个不同的对象上运行是可以的。如果在两个线程中使用相同的Scanner实例,除非同步对该对象的访问,否则您将遇到问题。但扫描仪的两个独立实例永远不会相互干扰 针对询问

我对使用
java.util.Scanner
感兴趣。我正在阅读,看到一行字说,如果没有外部同步,扫描仪对于多线程使用是不安全的。我能否确认这意味着在两个单独的线程中的两个单独的扫描仪对象在两个单独的文件上运行时可能会相互干扰


有人能帮我从外部同步扫描仪对象,以便进行安全的线程操作吗?

多线程使用是指在同一对象上运行的两个线程。两个线程在两个不同的对象上运行是可以的。

如果在两个线程中使用相同的Scanner实例,除非同步对该对象的访问,否则您将遇到问题。但扫描仪的两个独立实例永远不会相互干扰

针对询问如何同步的评论进行编辑

首先,您真的确定需要同步吗?您可以在不同的线程中安全地使用不同的scanner实例,而不会有任何危险。一个线程可以有
Scanner s1=新扫描仪(新文件(“/tmp/file1.txt”);

另一个线程可以具有
Scanner s2-新扫描仪(新文件(“/tmp/file2.txt”);

而且没有风险。不同的扫描器可以使用相同的文件、不同的文件或完全不同的数据源。但是,您仍然需要谨慎。正如Stephen C所指出的,如果两个不同的扫描器实例使用相同的流或读取器作为输入,则您仍然会得到中断操作,然后他们将从ea中窃取字符ch other。此警告适用于使用InputStream、Readable和ReadableByteChannel的构造函数

在多个线程中使用单个扫描程序的问题在于,它正在顺序地使用来自单个源的字符。如果有多个线程以不同步的方式使用这些字符,则每个线程将获得一些字符,而没有一个线程将获得所有字符。为了说明这一点,请想象一下您让扫描器读取字符串“qwertyuiop”,两个单独的线程同时调用函数
next()
,那么一个线程可能会看到“ertip”,另一个线程会看到“qwyuo”;这将是无用的

我的同步建议如下:

  • 不要使用多线程!即使是身体部位的截肢也比尝试使多线程应用程序稳定、可扩展和灵活更可取
  • 有时,您可以对非线程安全类(或封装和委托)进行子类化,并同步对基类(或委托)的调用:
    synchronized(this){super.next();}
    。但不要在Scanner中尝试此操作!有太多使用者方法,而且您不知道该类是如何在内部实现的,因此注定会失败!请参阅建议1
  • 我在这里尝试的是让一个线程运行扫描器,并将令牌送入ArrayBlockingQueue。这样,您将以正确的顺序获得进入队列的完整令牌。您可以从队列中读取任意数量的线程。但请注意,您的任何线程都可能会被阻止读取或删除除非您注意处理满或空的情况,否则写入此队列。无论您做什么,都有可能最终导致挂起的线程永远无法完成。请参见第1点。如果您希望有时调用不同的下一个方法(例如
    nextInt()
    nextDouble()
    )或使用has方法,这将变得复杂(例如,
    hasNextInt()
    hasNextDouble()
    ),但没有第2点那么复杂

  • 最后,我建议您看看第1点。

    您可以使用多个扫描仪,使用来自多个线程的不同数据源,而不会出现问题


    将一台扫描仪与多个线程一起使用会导致问题。

    我想在公认的答案中谈谈这一点


    如果在两个线程中使用同一个扫描仪实例,除非同步对对象的访问,否则您将遇到问题。但两个单独的扫描仪实例将永远不会相互干扰。

    实际上,两个单独的<代码>扫描器实例如果它们共享同一个输入源会互相干扰。考虑如果您有两个扫描器对象包装<代码>系统。在< /代码>中使用两个不同的线程。当您调用<代码> HasnExtTin()时,在一个

    扫描器上
    ,它将从
    系统中提前读取。在
    中有足够的字符来确定是否存在有效的整数。如果第一个线程没有调用
    nextInt()
    ,第二个线程将无法读取预读字符。它们将位于第一个
    扫描仪的内部缓冲区中


    实际上,一个扫描器通过“窃取”字符来干扰另一个扫描器。在同一个流上有两个扫描器是病态的。您的说法仅适用于不同输入流上的两个扫描器。

    您能否指定如何在外部同步扫描器对象以用于安全的线程操作?