【问题标题】:Why does starting my thread not call the run() method? [closed]为什么启动我的线程不调用 run() 方法? [关闭]
【发布时间】:2015-05-12 23:39:38
【问题描述】:

在第一种方法中,我只想为数组中的每个URL创建一个线程并解析它:

    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();
    }
}

然后我为我的可运行对象创建了一个单独的类,其中 run 方法创建了一个 bufferedReader 来扫描 html 文件并对其进行解析。

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");
    }
    }

}

我知道第一个方法何时被调用,即使我启动了线程,它也不会通过 runObject 类中的 run 方法。为什么是这样?

【问题讨论】:

  • 难以置信。你的证据呢?
  • 旁注。线程池值得考虑。 Executors.newFixedThreadPool

标签: java multithreading


【解决方案1】:

您的代码运行良好。你根本没有意识到。添加一些日志/输出消息,您将看到它。哦,顺便说一句,预计输入结束。这是简化的代码:

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");
        }
    }    
}

这是输出:

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

请注意,当您的读者刚刚开始时,您的主线程已经完成。一个词——多线程。

【讨论】:

    【解决方案2】:

    不过,我不喜欢它的质量。我知道我不是代码审查员。请试试这个!

    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类

    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();
        }
    }
    

    请考虑更好的设计。这些链接可以帮助您更好地编码。

    线程池是个不错的选择。
    http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

    CountDownLatch 用于完成所有线程http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

    Runobject 也可以是私有内部类。 Wait until child threads completed : Java

    免责声明:- 在其他问题和答案的帮助下回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      相关资源
      最近更新 更多