私はSAX(dd-plistライブラリ)で解析する大きなplist(Xml)ファイルを持っています。これは、解析のための大きなファイルであり、パフォーマンスの理由から私はマルチスレッドを使用する必要があります。私の目標は、plistファイルのキーの正確な数と同じスレッドの正確な数を持っています。キーとURLが等しい場合は、値を検索してURLと比較し、そうでない場合はnullを返し、スレッドをスキップしてキャンセルします(この値はHTMLコンテンツのタイトルであり、キーはplistに保存されているパス、およびurlは、Android WebViewのonPageFinishedでユーザーがクリックしてキャプチャしたリンクのURLです。もし私がコードを逃してしまったことを私が目標以上に教えてくれれば幸いです。 onPageFinishedの私WebFragment(android.support.v4.app.Fragment、では呼び出し可能ExecutiorService Javaを含むループを終了する方法(Android)
:ログここ
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;
}
}
}
されています:
ここ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...
}
はParsePlistThreadクラスです
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
同じファイル*を解析しようとするには複数のスレッドを使用していますか?... – Ordous
@Ordousはい、最初に私はマルチスレッドをせずにメインスレッドで行いました。 SAX、だから私は多分、スレッドのそれぞれが同じplistファイルの1行を読む複数のスレッドを使用できると思った... – Jack
OK、私はここであなたを落胆しようとはしていないが、かなり無駄。多くの場合、ボトルネックはファイルを読み込んでいるため、複数のスレッドでファイルを解析するのは馬鹿げた考えです。これはコア/スレッドの数ではなく、ここで問題となるアルゴリズムです。しかも、並行性がはっきりしていません。あなたの例では、実際には並行処理は行われません。単なるスレッドのハンドオフだけです。 "あなたのアプリが遅い場合は、単にマルチスレッド化してください!"実際にそれをプロファイリングし、問題がどこにあるのかを知ることができます。 – Ordous