求大神看看我写的这个程序有无线程问题

songzheng_741 2013-12-31 01:28:06
这是个计算内网IP的程序,网络平稳,但每次IP输出数量差别很大
package org.sz.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class IPUtils {

/**
* 获取所在内网所有IP
* @param args
* @throws InterruptedException
*/
public static void gainAllIp() throws InterruptedException {
final List<String> innerIp = Collections.synchronizedList(new ArrayList<String>());
final CyclicBarrier barrier = new CyclicBarrier(255, new IpShow(innerIp));
String hostAddress = getLocalIP();
int pos = hostAddress.lastIndexOf(".");
String wd = hostAddress.substring(0, pos + 1);
for (int i = 1; i <= 255; i++) {
String ip = wd + i;
PingIpThread thread = new IPUtils.PingIpThread(ip, barrier, innerIp);
thread.start();
}
}

public static class IpShow implements Runnable {
private List<String> innerIp;
public IpShow(List<String> innerIp) {
this.innerIp = innerIp;
}
@Override
public void run() {
System.out.println(innerIp.size());
for (String ip : innerIp) {
System.out.println(ip);
}
}
}

public static class PingIpThread extends Thread {
private String ip;
private CyclicBarrier barrier;
private List<String> list;
public PingIpThread(String ip, CyclicBarrier barrier, List<String> list) {
this.ip = ip;
this.barrier = barrier;
this.list = list;
}
public void run() {
try {
String cmd = "ping " + ip + " -n 1";
Process process = Runtime.getRuntime().exec(cmd);
//process.waitFor();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
String line = in.readLine();
while (line !=null) {
if (line !=null && !line.equals("")) {
if (line.substring(0, 2).equals("来自")
|| (line.length() > 10 && line.substring(0, 10)
.equals("Reply from"))) {
list.add(ip);
}
}
line = in.readLine();
}
} catch(IOException e) {

}
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
try {
barrier.await();
} catch (InterruptedException ie) {
ie.printStackTrace();
} catch (BrokenBarrierException bbe) {
bbe.printStackTrace();
}
}
}

public static String getLocalIP() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
public static String getLocalHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
public static String getCanonicalHostName() {
try {
return InetAddress.getLocalHost().getCanonicalHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
public static String getIPFromDomainName(String domainName) {
try {
return InetAddress.getByName(domainName).getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
public static String getDomainNameFromIP(String ip) {
try {
return InetAddress.getByAddress(getIPBytes(ip)).getCanonicalHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
private static byte[] getIPBytes(String ip) {
byte[] ipBytes = new byte[4];
String[] ipStr = ip.split("[.]");

for (int i = 0; i < 4; i++) {
int m = Integer.parseInt(ipStr[i]);
byte b= (byte)(m & 0xff);
ipBytes[i] = b;
}
return ipBytes;
}

public static void main(String[] args) throws InterruptedException {
gainAllIp();
gainAllIp();
}
}
...全文
182 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
songzheng_741 2014-01-02
  • 打赏
  • 举报
回复
引用 4 楼 raistlic 的回复:
ip段的计算方式有问题,并不是所有的网络子网掩码都是 255.255.255.0 IpShow 的 run 方法内迭代循环输出 list 的内容,而 list 的内容可能在别的线程内被改变,所以直接迭代不可能是线程安全的,Collections.synchronizedList(list) 方法的 JavaDOC 里对迭代有特别交代 ping 网络地址应该有更好的API可以用
感谢回答,是有更方便的Ping API,用了2Lping给的方法。因为用了栅栏,迭代线程是在其他线程计算IP线程之后才开始运行,所以应该不会出现ConcurrentModificationException
raistlic 2014-01-02
  • 打赏
  • 举报
回复
ip段的计算方式有问题,并不是所有的网络子网掩码都是 255.255.255.0 IpShow 的 run 方法内迭代循环输出 list 的内容,而 list 的内容可能在别的线程内被改变,所以直接迭代不可能是线程安全的,Collections.synchronizedList(list) 方法的 JavaDOC 里对迭代有特别交代 ping 网络地址应该有更好的API可以用
songzheng_741 2013-12-31
  • 打赏
  • 举报
回复
引用 1 楼 ghostkngiht 的回复:
需要搞的这么复杂吗?试试这个行不行

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class IPUtils {

    private static final List<String> innerIp = new ArrayList<String>();

    /**
     * 获取所在内网所有IP
     *
     * @throws InterruptedException
     * @throws java.net.UnknownHostException
     */
    public static void gainAllIp() throws InterruptedException, UnknownHostException, IOException {
        String hostAddress = getLocalIP();
        int pos = hostAddress.lastIndexOf(".");
        String wd = hostAddress.substring(0, pos + 1);
        for (int i = 1; i <= 255; i++) {
            String ip = wd + i;
            if (InetAddress.getByName(ip).isReachable(1000)) {
                innerIp.add(ip);
            }
        }
    }

    public static String getLocalIP() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        gainAllIp();
    }
}
不过我本机InetAddress.getLocalHost().getHostAddress();返回的是127.0.0.1,不知道你那能不能返回正确的IP。
多谢这位提醒
小陈杰帝 2013-12-31
  • 打赏
  • 举报
回复
我是来学习的~~~~~~~
ghostkngiht 2013-12-31
  • 打赏
  • 举报
回复
需要搞的这么复杂吗?试试这个行不行

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class IPUtils {

    private static final List<String> innerIp = new ArrayList<String>();

    /**
     * 获取所在内网所有IP
     *
     * @throws InterruptedException
     * @throws java.net.UnknownHostException
     */
    public static void gainAllIp() throws InterruptedException, UnknownHostException, IOException {
        String hostAddress = getLocalIP();
        int pos = hostAddress.lastIndexOf(".");
        String wd = hostAddress.substring(0, pos + 1);
        for (int i = 1; i <= 255; i++) {
            String ip = wd + i;
            if (InetAddress.getByName(ip).isReachable(1000)) {
                innerIp.add(ip);
            }
        }
    }

    public static String getLocalIP() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        gainAllIp();
    }
}
不过我本机InetAddress.getLocalHost().getHostAddress();返回的是127.0.0.1,不知道你那能不能返回正确的IP。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧