- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个很大的plist(Xml)文件,可以用SAX(dd-plist库)解析。由于它是一个大文件,并且出于性能原因,我不得不使用multiThreading,我的目标是要拥有与我的plist文件中的键的确切数目相同的确切线程数,我的意思是对于plist中的每个键,单线程搜索该值并将其与url比较,如果key和url相等,则返回key的值,否则返回null并跳过并取消该线程(该值是html Content的标题,key为存储在plist中的路径,而url是链接用户在用户单击并在Android WebView的onPageFinished中捕获的任何url。如果有人告诉我实现上述目标,我将不胜感激。
在我的WebFragment(android.support.v4.app.Fragment,在onPageFinished中:
import com.dd.plist.NSDictionary;
import com.dd.plist.NSObject;
import com.dd.plist.PropertyListParser;
...
try {
is = getResources().openRawResource(R.raw.title);
rootDict = (NSDictionary) PropertyListParser.parse(is);
dict = new LinkedHashMap<>();
dict = rootDict.getHashMap();
ExecutorService executor = Executors.newFixedThreadPool(rootDict.size());
Future<String> future;
String myStr = null;
String key;
NSObject value;
for (Map.Entry<String, NSObject> entry : dict.entrySet()) {
key = entry.getKey();
value = entry.getValue();
// following line is refer to WebFragment (line 285 where logs complain and crash because of the memory
future = executor.submit(new ParsePlistThread(key, value, url.substring(32).toString()));
myStr = future.get();
if (myStr != null && !myStr.isEmpty()) {
break;
} else {
//future.cancel(true);
}
}
executor.shutdown();
if (myStr != null) {
if (numTab == 0) {
titleTextView.setText(myStr);
}
} catch (Exception ex) {
//Handle exceptions...
}
import com.dd.plist.NSObject;
import java.util.concurrent.Callable;
/**
* Created by manager on 2016-08-18.
*/
public class ParsePlistThread implements Callable<String> {
public String key;
public NSObject valueObject;
public String url;
public ParsePlistThread(String key , NSObject valueObj , String url) {
this.key = key;
this.valueObject = valueObj;
this.url = url;
}
@Override
public String call() throws Exception {
if (key.equals(url)) {
return valueObject.toString();
} else
{
return null;
}
}
}
E/art: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"
08-19 09:52:50.328 28749-28749/ca.ccohs.oshanswers E/AndroidRuntime: FATAL EXCEPTION: main
Process: XXX, PID: 28749
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
at java.lang.Thread.nativeCreate(Native Method)
at java.lang.Thread.start(Thread.java:1063)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1327)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:103)
at ca.ccohs.oshanswers.ui.WebFragment$3.onPageFinished(WebFragment.java:285)
at com.android.webview.chromium.WebViewContentsClientAdapter.onPageFinished(WebViewContentsClientAdapter.java:531)
at org.chromium.android_webview.AwContentsClientCallbackHelper$MyHandler.handleMessage(AwContentsClientCallbackHelper.java:188)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6117)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
08-19 09:52:50.343 2850-29945/? E/android.os.Debug: ro.product_ship = true
08-19 09:52:50.343 2850-29945/? E/android.os.Debug: ro.debug_level = 0x4f4c
最佳答案
您的方法存在问题
除了将极小的任务放入其他线程的概念性问题(与实际计算相比,您将花费更多的时间来传递信息)之外,此代码还有两个主要问题:
1)您得到的实际错误。此错误是由于堆栈内存不足而引起的。 Java内存分为多个区域,最大和最常见的已知区域之一是“堆内存”。这是(几乎)所有对象居住的地方。鲜为人知的区域是“堆栈内存”。这是线程在其中获取内存以存储当前状态,堆栈跟踪,局部(方法)变量等的位置。创建Thread
时,将从该空间为其堆栈分配一些固定的内存。如果创建的线程过多,它将耗尽,并抛出诸如您遇到的错误之类的错误。
解决方案-重新使用线程!
执行程序具有内置功能,可以在完成任务时重用线程。在下面的更多内容。通常,CPU中的线程多于逻辑内核不会提高速度。
2)您实际上并没有在做任何事情。在循环中,您要向Executor
(executor.submit
方法)提交任务,然后等待任务完成(future.get
),然后转到下一行。因此,在创建新任务之前,您正在等待当前任务完成!您将不会有与此任务并行运行的2个任务。
最后一点是您不应该依赖多线程来加快文件处理。瓶颈几乎总是在读取文件。您很可能对它做一些愚蠢的事情,这会使它变慢。
多线程性能更好。
评论中提到,如果值得的话,看看如何解决这些错误可能很有用。下面是解决并发问题的半幼稚方法。
首先是第一-限制所需的线程。如果您在具有超线程的四核桌面上运行,我建议您使用6个线程,或者只是一个工作窃取池。我不确定什么是Android的好数字,但肯定比“非常大的文件”中的行数低。
ExecutorService executor = Executors.newFixedThreadPool(6);
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
List<Future<String>> tasks = new ArrayList<>();
for (Map.Entry<String, NSObject> entry : dict.entrySet()) {
key = entry.getKey();
value = entry.getValue();
tasks.add(executor.submit(new ParsePlistThread(key, value, url)));
}
String result;
for (Future<String> fut : tasks) {
String taskResult = fut.get();
if (taskResult != null && !taskResult.isEmpty()) {
result = taskResult;
break;
}
}
future.cancel
即可实现。我将代码留给您。通常,这比较困难,因为这将涉及线程间通信(您必须发信号通知另一个线程以适当地停止其执行,这可能并不容易)。
关于java - 如何退出包含Java的Callable ExecutiorService MultiThreading的循环(Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39042419/
我是 PHP 新手。我一直在脚本中使用 for 循环、while 循环、foreach 循环。我想知道 哪个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要
我在高中的编程课上,我的作业是制作一个基本的小计和顶级计算器,但我在一家餐馆工作,所以制作一个只能让你在一种食物中读到。因此,我尝试让它能够接收多种食品并将它们添加到一个价格变量中。抱歉,如果某些代码
这是我正在学习的一本教科书。 var ingredients = ["eggs", "milk", "flour", "sugar", "baking soda", "baking powder",
我正在从字符串中提取数字并将其传递给函数。我想给它加 1,然后返回字符串,同时保留前导零。我可以使用 while 循环来完成此操作,但不能使用 for 循环。 for 循环只是跳过零。 var add
编辑:我已经在程序的输出中进行了编辑。 该程序要求估计给定值 mu。用户给出一个值 mu,同时还提供了四个不等于 1 的不同数字(称为 w、x、y、z)。然后,程序尝试使用 de Jaeger 公式找
我正在编写一个算法,该算法对一个整数数组从末尾到开头执行一个大循环,其中包含一个 if 条件。第一次条件为假时,循环可以终止。 因此,对于 for 循环,如果条件为假,它会继续迭代并进行简单的变量更改
现在我已经习惯了在内存非常有限的情况下进行编程,但我没有答案的一个问题是:哪个内存效率更高;- for(;;) 或 while() ?还是它们可以平等互换?如果有的话,还要对效率问题发表评论! 最佳答
这个问题已经有答案了: How do I compare strings in Java? (23 个回答) 已关闭 8 年前。 我正在尝试创建一个小程序,我可以在其中读取该程序的单词。如果单词有 6
这个问题在这里已经有了答案: python : list index out of range error while iteratively popping elements (12 个答案) 关
我正在尝试向用户请求 4 到 10 之间的整数。如果他们回答超出该范围,它将进入循环。当用户第一次正确输入数字时,它不会中断并继续执行 else 语句。如果用户在 else 语句中正确输入数字,它将正
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我想要做的事情是使用循环创建一个数组,然后在另一个类中调用该数组,这不会做,也可能永远不会做。解决这个问题最好的方法是什么?我已经寻找了所有解决方案,但它们无法编译。感谢您的帮助。 import ja
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我正在模拟一家快餐店三个多小时。这三个小时分为 18 个间隔,每个间隔 600 秒。每个间隔都会输出有关这 600 秒内发生的情况的统计信息。 我原来的结构是这样的: int i; for (i=0;
这个问题已经有答案了: IE8 for...in enumerator (3 个回答) How do I check if an object has a specific property in J
哪个对性能更好?这可能与其他编程语言不一致,所以如果它们不同,或者如果你能用你对特定语言的知识回答我的问题,请解释。 我将使用 c++ 作为示例,但我想知道它在 java、c 或任何其他主流语言中的工
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我是 C 编程和编写代码的新手,以确定 M 测试用例的质因数分解。如果我一次只扫描一次,该功能本身就可以工作,但是当我尝试执行 M 次时却惨遭失败。 我不知道为什么 scanf() 循环有问题。 in
这个问题已经有答案了: JavaScript by reference vs. by value [duplicate] (4 个回答) 已关闭 3 年前。 我在使用 TSlint 时遇到问题,并且理
我尝试在下面的代码中添加 foreach 或 for 循环,以便为 Charts.js 创建多个数据集。这将允许我在此折线图上创建多条线。 我有一个 PHP 对象,我可以对其进行编码以稍后填充变量,但
我是一名优秀的程序员,十分优秀!