2

In the first method, I just want to create a thread for each URL in the array and parse it:

    public void readFriendData(String[] urls) {
    Thread[] urlThreads = new Thread[urls.length];
    for (int x = 0; x < urls.length; x++) {
        Runobject input = new Runobject(urls[x], this);
        Thread one = new Thread(input);
        urlThreads[x] = one;

    }

    for(int x = 0; x< urls.length; x++){
        urlThreads[x].start();
    }
}

And then I made a separate class for my runnable object, where the run method creates a bufferedReader to scan the html file and parses it.

package twitbook;
public class Runobject implements Runnable {
public String address;
public Twitbook net;

public Runobject(String theAdress, Twitbook net) {
    address = theAdress;
    this.net = net;

}

@Override
public void run() {
    try {
        URL url = new URL(address);
        URLConnection urlConnection = url.openConnection();

        BufferedReader scanner = new BufferedReader(new InputStreamReader(
                urlConnection.getInputStream()));

        String input = scanner.readLine();
        while (!input.equals("</body>")) {
            if (input.startsWith("<tr> <td>addperson</td>")) {
                input.replaceAll("<tr> <td>addperson</td>", "");
                input.replaceAll(" <td>", "");
                input.replaceAll("</td> </tr>", "");

                net.addUser(input);
            } else if (input.startsWith("<tr> <td>addfriend</td>")) {
                String[] bits = new String[2];
                input.replaceAll("<tr> <td>addfriend</td>", "");
                bits = input.split("</td> <td>");
                input.replaceAll(" <td>", "");
                input.replaceAll("</td> </tr>", "");

                net.friend(bits[0], bits[1]);
                net.friend(bits[1], bits[0]);

            }

            input = scanner.readLine();

        }
        scanner.close();

    } catch (IOException e) {
        System.out.println("bad URL");
    }
    }

}

I know when the first method is called, even though I started the threads, it doesn't go through the run method in the runObject class. Why is this?

kraiwo
  • 23
  • 2

2 Answers2

1

Your code works perfectly. You simply do not realize it. Add few logging/output messages and you will see it. Oh, by the way, anticipate end of input. Here is simplified code:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

public class Runobject implements Runnable {
    public String address;

    public static void main(String a[]) {
        System.out.println("Start");
        readFriendData(new String[] { "http://google.com", "http://yahoo.com" });
        System.out.println("End");
    }

    public static void readFriendData(String[] urls) {
        Thread[] urlThreads = new Thread[urls.length];
        for (int x = 0; x < urls.length; x++) {
            Runobject input = new Runobject(urls[x]);
            Thread one = new Thread(input);
            urlThreads[x] = one;

        }

        for (int x = 0; x < urls.length; x++) {
            urlThreads[x].start();
        }
    }

    public Runobject(String theAdress) {
        address = theAdress;
        System.out.println(address);
    }

    @Override
    public void run() {
        try {
            URL url = new URL(address);
            URLConnection urlConnection = url.openConnection();

            BufferedReader scanner = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream()));

            int countOfLines = 0;
            String input = scanner.readLine();
            while (input != null && !input.equals("</body>")) {
                countOfLines++;
                if (input.startsWith("<tr> <td>addperson</td>")) {
                    input.replaceAll("<tr> <td>addperson</td>", "");
                    input.replaceAll(" <td>", "");
                    input.replaceAll("</td> </tr>", "");

                    // net.addUser(input);
                } else if (input.startsWith("<tr> <td>addfriend</td>")) {
                    String[] bits = new String[2];
                    input.replaceAll("<tr> <td>addfriend</td>", "");
                    bits = input.split("</td> <td>");
                    input.replaceAll(" <td>", "");
                    input.replaceAll("</td> </tr>", "");

                    // net.friend(bits[0], bits[1]);
                    // net.friend(bits[1], bits[0]);

                }

                input = scanner.readLine();

            }
            scanner.close();
            System.out.println(address + " has " + countOfLines + " lines");
        } catch (IOException e) {
            System.out.println("bad URL");
        }
    }    
}

and here is output:

Start
http://google.com
http://yahoo.com
End
http://google.com has 8 lines
http://yahoo.com has 63 lines

Pay attention that your main thread is already finished when your readers just started yet. One word - multithreading.

user207421
  • 305,947
  • 44
  • 307
  • 483
Alex
  • 4,457
  • 2
  • 20
  • 59
0

Though, I don't like the quality of it. I know I am not code reviewer. Please try this!

public static void main(String[] args) {
    Twitbook twitbook = new Twitbook();
    String[] urls = new String[2];
    urls[0] = "www.google.com";
    urls[0] = "www.yahoo.com";
    twitbook.readFriendData(urls);
}

public void readFriendData(String[] urls) {
    CountDownLatch latch = new CountDownLatch(urls.length);
    for (int x = 0; x < urls.length; x++) {
        Runobject input = new Runobject(urls[x], this, latch);
        input.run();
    }
    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return;
}

public synchronized void addUser(String input) {

    return;
}

public synchronized void friend(String bits1, String bits2) {

    return;
}

RunObject class here

public class Runobject implements Runnable {
public String address;
public Twitbook net;
public CountDownLatch latch;

public Runobject(String theAdress, Twitbook net, CountDownLatch latch) {
    address = theAdress;
    this.net = net;
}

@Override
public void run() {
    try {
        URL url = new URL(address);
        URLConnection urlConnection = url.openConnection();

        BufferedReader scanner = new BufferedReader(new InputStreamReader(
                urlConnection.getInputStream()));

        String input = scanner.readLine();
        while (!input.equals("</body>")) {
            if (input.startsWith("<tr> <td>addperson</td>")) {
                input.replaceAll("<tr> <td>addperson</td>", "");
                input.replaceAll(" <td>", "");
                input.replaceAll("</td> </tr>", "");

                net.addUser(input);
            } else if (input.startsWith("<tr> <td>addfriend</td>")) {
                String[] bits = new String[2];
                input.replaceAll("<tr> <td>addfriend</td>", "");
                bits = input.split("</td> <td>");
                input.replaceAll(" <td>", "");
                input.replaceAll("</td> </tr>", "");

                net.friend(bits[0], bits[1]);
                net.friend(bits[1], bits[0]);

            }

            input = scanner.readLine();

        }
        scanner.close();
    } catch (IOException e) {
        System.out.println("bad URL");
    } finally {
        latch.countDown();
    }
}

Please consider better design. These links may help you to do better coding.

Thread pool is a good option.
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

CountDownLatch for finish all threads http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

Runobject can be a private inner class as well. Wait until child threads completed : Java

disclaimer :- Answered with help of other question and answers.

Community
  • 1
  • 1
bobs_007
  • 178
  • 1
  • 10