开发者

how to use Thread in java?

i have code use googleseach API

I want to use Thread to improve speed of my program. But i have a problem

here is code

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import com.yahoo.search.WebSearchResult;

/**
 * Simple Search using Google ajax Web Services
 * 
 * @author Daniel Jones Copyright 2006 Daniel Jones Licensed under BSD open
 *         source license http://www.opensource.org/licenses/bsd-license.php
 */

public class GoogleSearchEngine extends Thread {



    private String queryString;
    private int maxResult;
    private ArrayList<String> resultGoogleArrayList = null;



    public ArrayList<String> getResultGoogleArrayList() {
        return resultGoogleArrayList;
    }

    public void setResultGoogleArrayList(ArrayList<String> resultGoogleArrayList) {
        this.resultGoogleArrayList = resultGoogleArrayList;
    }

    public String getQueryString() {
        return queryString;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    public int getMaxResult() {
        return maxResult;
    }

    public void setMaxResult(int maxResult) {
        this.maxResult = maxResult;
    }

    // Put your website here
    public final static String HTTP_REFERER = "http://www.example.com/";

    public static ArrayList<String> makeQuery(String query, int maxResult) {
        ArrayList<String> finalArray = new ArrayList<String>();
        ArrayList<String> returnArray = new ArrayList<String>();
        try {       
            query = URLEncoder.encode(query, "UTF-8");
            int i = 0;
            String line = "";
            StringBuilder builder = new StringBuilder();
            while (true) {

                // Call GoogleAjaxAPI to submit the query
                URL url = new URL("http://ajax.googleapis.com/ajax/services/search/web?start=" + i + "&rsz=large&v=1.0&q=" + query);

                URLConnection connection = 开发者_开发问答url.openConnection();
                if (connection == null) {
                    break;
                }

                // Value i to stop while or Max result
                if (i >= maxResult) {
                    break;
                }

                connection.addRequestProperty("Referer", HTTP_REFERER);

                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }

                String response = builder.toString();
                JSONObject json = new JSONObject(response);
                JSONArray ja = json.getJSONObject("responseData").getJSONArray("results");

                for (int j = 0; j < ja.length(); j++) {
                    try {
                        JSONObject k = ja.getJSONObject(j);     
                        // Break string into 2 parts: URL and Title by <br>

                        returnArray.add(k.getString("url") + "<br>" + k.getString("titleNoFormatting"));
                    } 
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                i += 8;
            }

            // Remove objects that is over the max number result required
            if (returnArray.size() > maxResult) {
                for (int k=0; k<maxResult; k++){
                    finalArray.add(returnArray.get(k));
                }
            }
            else 
                return returnArray;

            return finalArray;
        } 
        catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        //super.run();
        this.resultGoogleArrayList = GoogleSearchEngine.makeQuery(queryString, maxResult);
        System.out.println("Code run here ");
    }
    public  static void main(String[] args) 
    {
        Thread test = new GoogleSearchEngine(); 
        ((GoogleSearchEngine) test).setQueryString("data ");
        ((GoogleSearchEngine) test).setMaxResult(10);
        test.start();   
        ArrayList<String> returnGoogleArrayList = null;
        returnGoogleArrayList = ((GoogleSearchEngine) test).getResultGoogleArrayList();
         System.out.print("contents of al:" + returnGoogleArrayList);       
    }
}

when i run it, it can run into run method but it don't excute make query methor and return null array.

when i do't use Thread it can nomal .

Can you give me the reason why ? or give a sulution

Thanks


One of the main problems is that you didn't wait for the asynchronous computation to complete. You can wait by using Thread.join(), but it'll be even better if you use a Future<V>, such as a FutureTask<V> instead.

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready.

API links

  • Package java.util.concurrent (contains many high level concurrency utilities)
    • interface Future<V> (represents result of asynchronous computation)
      • interface RunnableFuture<V> (a Future that is Runnable)
        • class FutureTask<V> (implementation that wraps a Callable or Runnable object)
    • interface Executor ("normally used instead of explicitly creating threads")
    • class Executors (provides factory and utility methods)

Tutorials and lessons

  • Concurrency
    • High level concurrency objects
  • Concurrency utilities language guide

See also

  • Effective Java 2nd Edition
    • Item 68: Prefer executors and tasks to threads
    • Item 69: Prefer concurrency utilities to wait and notify


Your problem is simply that you're not waiting for the thread to perform its job, so you can't get the result. This can be fixed by simply doing

test.join(); 

before getting the result. Of course, that way the code isn't any faster than if you were doing everything in the main thread. Threads don't make things magically faster. You'll only get a benefit if you do multiple queries in parallel.


I believe you need to wait for the thread to complete before you can read the results. Use Thread.join() for that purpose.


  1. You don't wait for the thread to finish its calculation before getting the result, therefore you won't get the result.
  2. Doing the same work in a single new thread will not be any faster than doing it in the main thread.
  3. Doing multiple requests in multiple threads may be faster than doing them serially in a single thread.
  4. You should avoid handling threads directly when it's much simpler to use a thread pool (via an ExecutorService implementations as returned by one of the helper methods in Executors) which gives the same benefits and keeps you from doing all the manual synchronizaton and waiting, which is very error prone.


when you call test.start(); the new thread test is started, while the original main thread continues .. you then immediately continue processing on the main thread, calling test.getResultGoogleArrayList() which at that point (immediately) is still null as the thread test is most likely still processing the method makeQuery.

what you are trying to do is not really geared towards multi-threading and you are not likely to see any performance improvements simply by executing something on its own thread.

multi-threading is only useful if you have more than one task that can be processed concurrently, whereas what you are doing fits the linear or synchronous paradigm.


Before you start trying 'to use threads to improve the speed of your program' you should understand exactly what threading is. It is not some magic tool that just makes things faster. It allows you to perform multiple tasks 'simultaneously', depending on your hardware etc. If you have a single core processor it won't be simultaneous but execution can switch from one thread to the other whenever one thread has to wait for something to happen (e.g. user interaction etc.). There are other reasons for threads to switch execution and it depends on a lot of factors, which you don't really need to know, just appreciate that you can't take anything for granted when it comes to threading (don't assume something will happen at a specific time unless you specifically tell it to do so).

In your example above you have 2 threads, the main thread and the GoogleSearchEngine thread. In the main thread you create the second thread and tell it to start. But as I said they can both run simultaneously so execution in the main thread will continue onto the next line to get the results, but the other thread may not even have started, or at least not got round to doing anything worthwhile, which is why you are getting null.

In this case there is absolutely no reason to use multiple threads. Your program does one task then ends, so it might as well do it all in one thread.

The sun java tutorial on concurrency.


It is making call to your makeQuery method but getting connection timeout exception as appended below.

Call test.join(); before printing the content to avoid abrupt ending of program. Handle this connection exception as per your need.

I would also recommend instead of using join() as an alternate you can use timed waiting mechanism like wait(timeout) or CountDounLatch.await(timeout) etc

java.net.ConnectException: Connection timed out: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
....
....
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:570)
    at  at co.uk.mak.GoogleSearchEngine.makeQuery(GoogleSearchEngine.java:81)
    at co.uk.mak.GoogleSearchEngine.run(GoogleSearchEngine.java:124)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜