【问题标题】:Sharing a Scanner between two threads在两个线程之间共享一个 Scanner
【发布时间】:2012-10-25 11:44:19
【问题描述】:

如何在两个线程之间共享 Scanner 对象,以便在一个线程中将值传递给标准 i/p 流并在另一个线程中显示?

我创建了如下两个线程:

Thread1 我使用了以下代码:

while(true)
{

//Thread.currentThread().sleep(5000); // if I used this it is printing ABCD
str = System1Class.scan.nextLine();
System.out.println(str);
}

Thread2 我使用下面的代码:

String st = "ABCD";
InputStream is = new ByteArrayInputStream(st.getBytes());
System.setIn(is);
ThreadMainClass.scan  = new Scanner(System.in); // here I am trying to refresh the     global object "scan"

这里的 'scan' 对象是在 ThreadMainClass 类中全局创建的:

public static Scanner scan = new Scanner(System.in);

两个线程都在访问它。我的要求是:我想在从 Thread2 传递的 Thread1 中显示“ABCD”。它正在显示如果我放了一些延迟,以便在 Thread1 中的行之前创建 Scanner 对象:

str = System1Class.scan.nextLine();

但我不希望两个使用任何延迟。那么我有什么办法吗?我想在从 Thread2 传递的那一刻显示“ABCD”。与此同时,Thread1 应该等待来自控制台的数据,即 Thread1 不应该等待来自 Thread2 的任何通知。如果数据是从 Thread2 传递的,只需获取它并打印它,否则它应该只从控制台等待。

我想我需要一种方法来刷新 Thread2 中的“扫描”对象,但我不确定。 :)

提前致谢

【问题讨论】:

  • 您可以通过ManualResetEvent同步2个线程来实现,当thread2已经将值读入scanner时,thread2会通知thread1。
  • @Thinhbk 这是否意味着 Thread1 将等待来自 Thread2 的通知?我想要的是我不想等待来自 Thread2 的通知。 Thread1 应该独立工作,等待来自控制台的输入。它还应该能够随时从 Thread2 获取值。

标签: java


【解决方案1】:

要显示它传递的同一个实例,您需要调用类中的一个方法,将AtomicBoolean 变量设置为true。您将不得不编写一个循环并检查该变量的真值的方法。如果是true,则立即打印。

同时确保你synchronizeing你的读写线程

您也可以通过在 Java 中创建自己的事件

来做到这一点

阅读本教程中有关此方法的所有信息:

How to create your own events in Java

【讨论】:

  • 我已经更新了我的帖子,请检查使用 AtomicBoolean 是否仍然适用。谢谢。
【解决方案2】:

您可以使用 wait() 和 notify() 方法同步 2 个线程。

在全局类中:

Object wh = new Object();

在thread1的代码中:

while(true)
{

//Thread.currentThread().sleep(5000); // if I used this it is printing ABCD
//Wait thread2 to notify
// Prevent IllegalMonitorStateException occurs
synchronized(wh) {
    wh.wait();
}catch (InterruptedException e) {
    e.printStackTrace();
}
str = System1Class.scan.nextLine();
System.out.println(str);
}

在thread2的代码中:

String st = "ABCD";
InputStream is = new ByteArrayInputStream(st.getBytes());
System.setIn(is);
ThreadMainClass.scan  = new Scanner(System.in); // here I am trying to refresh the     global object "scan"
//Notify thread1
// Prevent IllegalMonitorStateException occurs
synchronized(wh) {
    wh.notify();
}catch (InterruptedException e) {
    e.printStackTrace();
}

HTH。

【讨论】:

  • 如果我使用上述同步,那么我将等待 Thread2,这与使用 sleep(5000) 几乎相似。这不是我想要的。每当有来自控制台的输入或每当从 Thread2 传递“ABCD”时,我都想为 str(在 Thread1 中)赋值。
  • @Angom:这里的方法与使用 sleep(5000) 完全不同,因为使用 sleep(5000) 不能保证 String 值将从 thread2 传递到 thread1,因为有执行thread1 在 thread2 初始化 Scanner 对象之前获取 Scanner 对象的路径。见java67.blogspot.com/2012/08/…
猜你喜欢
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多