简体   繁体   中英

Multi threads in Java

I have some class. For example:

public class Data {
    private String name;

    public Data(String url) {
        // There is download something from the Internet and set field "name".
    }

    public String getName() {
        return name;
    }
}

In some method I need to initialize array of objects Data.

ArrayList<Data> list = new ArrayList<Data>;
for(int i=0; i<max; i++) {
    list.add(new Data("http://localhost/" + String.valueOf(i)));
}

But it is to long. I wanna do this:

final ArrayList<Data> list = new ArrayList<Data>;
for(int i=0; i<max; i++) {
    final int tmp = i;
    new Thread() {

        public void run() {
            list.add(new Data("http://localhost/" + String.valueOf(tmp)));
        }   

    }.start();

}

But the main thread ends sooner than the others and variable list is empty. What should I do? Help pls :)

UP. That is not too fast to download some data from the Internet that's why I've created several threads.

Instead of dealing with the low level details of the Thread API, you could use the java concurrent package, with an executor to handle the threads (I don't know what ListArray is but if it is not thread safe you will have issues with the solution proposed some of the other answers: adding a join will not be sufficient).

For example, a simplified example would be:

final ExecutorService executor = Executors.newFixedThreadPool(10);
final List<Future<Data>> list = new ArrayList<Future<Data>>(max);

for (int i = 0; i < max; i++) {
    final int tmp = i;
    Callable<Data> c = new Callable<Data>() {
        @Override
        public Data call() {
            return new Data("http://localhost/" + tmp);
        }
    };
    list.add(executor.submit(c));
}

executor.shutdown();

for (Future<Data> future : list) {
    Data data = future.get(); //will block until the page has been downloaded
    //use the data
}

Ideally, you whould add some error handling around future.get() , as it will throw an ExecutionException if your task throws an exception, which I suppose could happen if the page is not availble for example.

1. When you fire the Another thread, that does the work of getting the data from net and populating the list, immediately after that use join() method.

2. join() method will not let the next line to execute before the run() method of the thread on which it is called has finish().

3. So your main() method will not be executed before the list is populated as you have used join() to hold the execution before the other thread is done.....

In your main use Thread.join to wait for the child threads to complete

    Thread[] threads = new Thread[max];
    final List<Data> list = Collections.synchronizedList(new ArrayList<Data>());
    for(int i=0; i< max; i++) {
        final int tmp = i;
        Thread t = new Thread() {

            public void run() {
                list.add(new Data("http://localhost/" + String.valueOf(tmp)));
            }   

        };
        t.start();
        threads[i] = t;
    }
    for (Thread t : threads) {
        t.join();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM