0

それを行うエレガントな方法はありますか?それとも、より良い設計パターンを使用できるため、常に回避できますか?

import java.util.ArrayList;
import java.util.List;

public class ForTest {

    List<String> ls = new ArrayList<String>();

    public static void main(String[] args) {
        ForTest forTest=new ForTest();
        System.out.println(forTest.ls.size());

        new Thread(new Worker(forTest.ls)).start();
        //size() does not change at all
        System.out.println(forTest.ls.size());
    }
}

class Worker implements Runnable{
    List<String> list;
    public Worker(List<String> li) {
        this.list = li;
    }

    public void run(){
        this.list.add("newItem");
    }
}
4

5 に答える 5

1

新しいスレッドが実際にコードの実行を開始するのを待ちます+forTestそれにアクセスできるように最終的にします(スレッドセーフなコレクションも使用します-最高の非同期別名ノンブロッキング)例

import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ForTest {

    Collection<String> ls = new ConcurrentLinkedQueue<String>();

    public static void main(String[] args) throws InterruptedException {
        final ForTest forTest = new ForTest();

        System.out.println(forTest.ls.size());

        int threads = 10;

        for ( int i=0; i<threads; i++ ) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    forTest.ls.add("newItem");
                }

            }).start();
        }

        Thread.sleep(1000);// wait for it !

        System.out.println(forTest.ls.size()); // 10 unless your threads are really slow
    }

}
于 2013-07-31T14:46:46.097 に答える
1

スレッディングのアイデアが欠けているようです。印刷するまでにワーカーが ls を更新していない可能性があるため、コードは機能しません。スレッドを使用している場合、スレッドは状態を通信する必要があります。これはすべて非常に複雑です。スレッドに関する Java チュートリアルを読むことをお勧めしますhttp://docs.oracle.com/javase/tutorial/essential/concurrency/

于 2013-07-31T14:37:04.687 に答える