2

ここにいくつかのコードを与えます

 public void doScan() {
    Log.i(LOG_TAG, "Start scanning");

    ExecutorService executor = Executors.newFixedThreadPool(NB_THREADS);
    for(int dest=0; dest<255; dest++) {
        String host = "192.168.5." + dest; //add net address instead of hardcoding
        executor.execute(pingRunnable(host));
    }

    Log.i(LOG_TAG, "Waiting for executor to terminate...");
    executor.shutdown();
    try { executor.awaitTermination(10*1000, TimeUnit.MILLISECONDS); } catch (InterruptedException ignored) { }
    Log.i(LOG_TAG, "Scan finished");
}


private Runnable pingRunnable(final String host) {
    return new Runnable() {
        public void run() {
            Log.v(LOG_TAG, "Pinging " + host + "...");
            try {
                Socket s = null;
                s = new Socket(InetAddress.getByName(host), ACES_PORT);

                Log.v(LOG_TAG, "conn:"+s.toString());
                if(s.isConnected()){
                    Log.v(LOG_TAG, "connected " + host);
                    foundDevicesArray.add(host);
                }


            } catch (UnknownHostException e) {
                Log.e(LOG_TAG, "Not found", e);
            } catch (IOException e) {
                Log.e(LOG_TAG, "IO Error", e);
            }
        }
    };
}

ホストがスレッド内で接続されている場合、ホストを保存しようとしています。

私はグローバルを持っています(私はAndroidを初めて使用するので、それが何と呼ばれるかわかりません)スレッド内でArrayList.add(host)を実行すると、クラッシュします。取得方法がわかりません。クラッシュからの通常のエラーメッセージ。

4

1 に答える 1

2

変数に null 以外の値を与えるには、次のように変数を初期化する必要があります。

static List<String> foundDevicesArray = new ArrayList<String> ();

ただし、配列リストはスレッド セーフではないため、並行性の問題を回避するために、代わりにCopyOnWriteArrayListなどのスレッド セーフなコレクションを使用する必要があります。

そのコレクションもListインターフェイスを実装しているため、宣言を変更するだけで済み、残りのコードはそのままにしておくことができます。

static List<String> foundDevicesArray = new CopyOnWriteArrayList<String> ();

最後に、CopyOnWriteArrayList は、基になる配列が変更されるたびにそのコピーを作成することで、スレッド セーフを実現します。配列が頻繁に変更されるが、競合が激しいわけではない (まったく同時に配列にアクセスしようとするスレッドが多くない)場合は、メモリ使用量の観点から同期リストの方が適している可能性があります。パフォーマンスとメモリ使用量を測定して、十分な情報に基づいた決定を下します。

static List<String> foundDevicesArray =
                 Collections.synchronizedList(new ArrayList<String> ());
于 2013-02-04T18:02:46.880 に答える