【问题标题】:Java changing string value in threadJava在线程中更改字符串值
【发布时间】:2014-04-30 05:33:05
【问题描述】:

我正在从我的 java 应用程序向 php 页面发送一些 json,如果成功,它会回显“完成”。 json 和 php 运行良好。我正在尝试将字符串传递给线程,然后将字符串的值更改为来自线程中 php 的回显,当线程完成时,我想使用 if 语句来确定 URL 连接是否成功完成...我只是无法从线程中获取字符串的值。

这是我的代码:

main.java

final String line = "unfinished";
Thread iURL = new instrURL(line, jsonArray);
iURL.start();

while(iURL.isAlive())
{
    System.out.println("In wait loop");
}


System.out.println(line);

if(line.trim() == "finished")
{
    System.out.println("Made it to finished");
}
else
{
    System.out.println("Did not make it to finished");
}

instrURL.java

public class instrURL extends Thread{

String line;
String jsonArray;

public instrURL(String line, String jsonArray)
{
    this.line = line;
    this.jsonArray = jsonArray;
}

public void run()
{

    try 
    {
        URL url = new URL("http://fake.php?jsonArray="+URLEncoder.encode(jsonArray, "UTF-8"));

        URLConnection conn = url.openConnection();

        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        line = rd.readLine();

        System.out.println(line);

        rd.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

    }

控制台:

在等待while循环中 在等待while循环中 ... ... ... 在等待while循环中 完成的 在等待while循环中 在等待while循环中 在等待while循环中 未完成 没有完成

正如您从控制台中看到的,线程已完成,但一旦超出线程,字符串值仍未完成。

任何帮助将不胜感激。

【问题讨论】:

  • 关于== "finished"how-do-i-compare-strings-in-java
  • 我看不到您将 any 字符串设置为 "finished" 的任何地方,那么即使在您修复了== 有问题吗?
  • Java 是按值传递的,因此您无法更新 line 的值,除非您明确分配新值。但是你不能因为line被声明为final
  • Sorry changed String line to line = rd.readLine();
  • @OP 不过,if(line.trim() == "finished") 永远不会是真的。

标签: java string multithreading


【解决方案1】:

您的进程中至少有四个不同的String 引用变量,名称为line,并且对其中一个的更新不会反映在其他变量中,这就是您的程序未按预期运行的原因:

  1. final String line = "unfinished"; in main.java - 看起来像一个 堆栈上的局部变量
  2. instrURL(String line, - 一个参数 instrURL 构造函数
  3. instrURL.line instrURL 中的成员 类
  4. String line; instrURL 中run() 方法中的本地

所有这些都是不同的引用,因此分配给一个不会影响其他任何一个。甚至除此之外,我在 instrURL 类中根本看不到任何对 line 风格的任何分配。

一般来说,您应该使用已建立的线程间通信方法,例如Future,或在锁下共享静态,但可能最接近您想要的方法是在某处声明一个静态易失性字符串行,并参考它在 main 和您的线程类中,并删除所有其他行的副本。

【讨论】:

  • 在将 final 更改为 public static 并更改我的构建路径后,我能够让它工作。谢谢!
  • public static 成员?这是糟糕的设计,有两个方面。如果您不想使用Future,最好的设计是让您的主创建一个带有String 字段的可变 对象,并在构造@987654334 时使用该对象引用@,将其建立为 main 和线程将共享的对象。
  • 我认为,糟糕的设计有点超出这一点——考虑到示例中的错误数量(它无法编译)。我已经提到了使用Future 的最佳实践,但我还包括了静态变量的想法,以至少展示最小的工作示例来说明为什么现有代码没有共享任何内容。
【解决方案2】:

Java 用 equals 方法比较字符串而不是 ==

if(null!line && line.trim().equals("finished"))
    {
        System.out.println("Made it to finished");
    }

在运行方法中,您没有从缓冲读取器读取数据,也没有更改行的值,这就是为什么您得到与“未完成”相同的值,您需要像这样读取数据

 String currentLine
    while ((currentLine = br.readLine()) != null) {
        System.out.println(sCurrentLine);
    }

从流中读取数据后,将行字符串中的值设置为

line="finished";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 2017-02-27
    • 1970-01-01
    相关资源
    最近更新 更多