所以这是我实现Runnable的类的代码。
public class SeedDownload implements Runnable {
private StringBuilder htmlSB;
private String bingSeed;
public SeedDownload(StringBuilder string) {
htmlSB = string;
}
public void run() {
Pattern pattern = Pattern.compile("class=\"b_algo\"><h2><a href=\"(.+?)\" h=\"");
Matcher matcher = pattern.matcher(htmlSB);
if (matcher.find()) {
bingSeed = matcher.group(1);
System.out.println(bingSeed);
}
} //End of run
public String getUrlLink() {
return bingSeed;
}
}
这是我主要课程中的代码。
StringBuilder htmlResult = PageRead.readPage(String.format("https://bing.com/search?q=%s", query));
System.out.println(htmlResult);
SeedDownload sdBing = new SeedDownload(htmlResult);
Thread bingThread = new Thread(sdBing);
bingThread.start();
System.out.println(sdBing.getUrlLink());
这是跑步时的输出。
&#34;空
显然,run方法中的print可以访问变量,而在主类中,它无法访问。是否与run()方法被停止并且其内容无法访问有关?
答案 0 :(得分:1)
你只是有一个volatilness问题,getter没有检索字符串的更新值,所以你的字符串对象必须是易变的!所以你可以确定在调用getter时获得更新的值
更改此
private String bingSeed;
带
private volatile String bingSeed;
来自oracle doc的:
使用volatile变量可降低内存一致性的风险 错误,因为对volatile变量的任何写入都会建立一个 在与之后的相关读取之前发生 变量。这意味着始终对volatile变量进行更改 其他线程可见。更重要的是,它还意味着当a 线程读取一个volatile变量,它不仅看到最新的变化 对于挥发性,还有导致代码的副作用 变化
答案 1 :(得分:1)
并不是因为它不可访问,而是因为变量bingSeed的修改发生在另一个线程而不是主线程,所以主线程的System.out.println()执行WHEN bingSeed仍为空
你有选择,要么等待线程完成同步,要么将线程提交给执行者服务并轮询结果
答案 2 :(得分:1)
你有两个主要问题
当你跑步时
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
<div>
<img src="{{ vich_uploader_asset(object, 'logoFichier') }}" alt="" style=""/>
</div>
{% endblock %}
您假设 bingThread.start();
System.out.println(sdBing.getUrlLink());
已经开始并且已经为Thread
分配了一个值 - 这可能不是这种情况,所以在致电bingSeed
之前确保getUrlLink
已完成添加
Thread
其次,要确保使用bingThread.join();
的最新值,请将其设置为易失性,如
bingSeed
答案 3 :(得分:0)
线程独立地生成它的结果,执行异步或后台处理。所以线程将独立地产生结果,但java程序可能已经走了很远,在它对此线程的请求之后。所以没有结果到达java程序,但结果是由线程正确给出的。这就是为什么它是null。请使用volatile
关键字。
答案 4 :(得分:0)
在您的代码中,有两种获取空值的可能性,即
1)matcher.find()给出错误的结果,在这种情况下你会得到一个非结果 初始值,即null。
2)在线程分配值之前,您的print语句正在执行 到bingSeed
你可以通过为matcher.find()块提供真值来检查这一点 在这种情况下,如果匹配器没有任何匹配,您将获得空值。
此外,对于第二点,您可以让线程等待并让bingSeed初始化。
`bingThread.start();
Thread.sleep(millis); // it will halt your main thread and you will get your variable value.
System.out.println(sdBing.getUrlLink());`
我试过了,这些检查后它运作良好