-1

ExecutorServiceに問題があります。ExecutorServiceを含むRunnableクラスを呼び出すGUIのボタンがあります。ExecutorService(またはメインスレッド)を停止するためにすべてを試しましたが、終了する方法が見つかりませんでした。これが私のコードです。あなたの答えとアドバイスを投稿してください。よろしくお願いします。

public void actionPerformed(ActionEvent e) {
    final FindGateWaysAndIps scanner = new FindGateWaysAndIps();
    if (e.getActionCommand()=="Start Scan"){
        scanner.start();
    }
    if (e.getActionCommand()=="Stop Scan"){
                scanner.interrupt();
                scanner.stopScans();
    }
}

クラス「FindGateWaysAndIps」

String ip = "192.168.";
String sql =" ";
static volatile boolean stop = false;
PingResult AllResaults = new PingResult();
int [] AllGateWays = new int [256];

final int NUM_THREADS = Runtime.getRuntime().availableProcessors(); 
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS*5);

public void run() {
    stop=true;
    while(stop){
    for (;GateWayKey<=GateWayKeyStop;GateWayKey++){
        if (!stop){
            exec.shutdownNow();
            Thread.currentThread().interrupt();
            break;
        }
        ip="192.168."+GateWayKey+".1";
        AllSQLs.add(exec.submit((new PingTask(ip,GateWayKey,true))));
    }
    if (!stop) {
        exec.shutdownNow();
        Thread.currentThread().interrupt();
        break;
    }
    AllGateWays=GetVectorData.GiveMeGateWays();
    for (int j=0; j<= AllGateWays.length;j++){
        System.out.println("stop je: "+stop);
        if (!stop){
            exec.shutdownNow();
            Thread.currentThread().interrupt();
            break;
        }
        removeDuplicateinVectors();
        //System.out.println("Sada je j"+j);
        for (;SubNetKey<=SubNetKeyStop;SubNetKey++){
            if (!stop){
                exec.shutdownNow();
                Thread.currentThread().interrupt();
                break;
            }
            ip="192.168."+AllGateWays[j]+"."+SubNetKey;         
            AllSQLs.add (exec.submit((new PingTask(ip,AllGateWays[j],false))));
        }

        // Process the result here (this is where you insert into the DB)
        //WriteAllDataIntoDataBase();
    }
    exec.shutdown();
    //WriteAllDataIntoDataBase();
}

public void stopScans(){
    exec.shutdownNow();
    stop=false;
}

申し訳ありませんが、PingTaskクラスです

public class PingTask implements Callable <String> {
    String ips;
    String sql;
    PingResult PassDataToExternalClass = new PingResult();
    //FindGateWaysAndIps DataProccesor = new FindGateWaysAndIps();  
    int GateWay;
    ScanFrame MonitorData = new ScanFrame();
    boolean GateWayORSubNet;
    int [] AllGateWays = new int [256];
    int i=0;
    public int[] GiveMeGateWays(){
        return AllGateWays;
    }
    public PingTask (){
    }
    public PingTask (String ip, int GateWayKey, boolean GateWayORSubNets){
        ips=ip;
        GateWay=GateWayKey;
        GateWayORSubNet=GateWayORSubNets;
    }

    public String call(){
        InetAddress address;
        try {
            address = InetAddress.getByName(ips);//ako nade gateway neka skoci u petlju u kojoj nade IP adrese pripadajuceg gatewaya
            System.out.println("PINGAM: "+ips);
            try {
                if (address.isReachable(2000)) { //pinga gatewaya s 1000ms (jeli je moguce ovo smanjiti da se ubrza proces)?
                    System.out.println("Nasa sam IP: "+ips);
                    AllGateWays[i]=GateWay;
                    i++;
                        MonitorData.WriteMonitorData(ips,address.getHostName().toString(),"2000","da");

                    if (GateWayORSubNet){
                            sql="REPLACE INTO `gateways` (`ID_GATEWAY` , `GATEWAY_IP` , `GATEWAY_NAME`) VALUES ('"+GateWay+"', '"+ips+"', '"+address.getHostName().toString()+"');";
                            return sql;
                        }
                        else{
                            sql="REPLACE INTO `subnets` (`IP` , `COMPUTER_NAME` , `GATEWAY_KEY`) VALUES ('"+ips+"', '"+address.getHostName().toString()+"', '"+GateWay+"');";
                            return sql;
                        }
                    } else {
                            return ";";
                    }
                } catch (IOException e) {
                    return ";";
                }
            } catch (UnknownHostException e) {
                return ";";
            }
    }
}
4

3 に答える 3

1

事実上、スレッドを停止するには、ExecutorService によって初期化されたプーラー内の各スレッドで、このスレッドが中断されたときの処理を定義する必要があります。

これが、デーモンが次のように開始する理由です。

while(true){
}

これは適切ではなく、スレッド プーラーをシャットダウンできない原因の 1 つです。

たとえば、好む:

while(!Thread.currentThread.isInterrupted){
}
//do here what to do in order to exit and clean safely your job and used resources like open filed.

しかし、これでも、何がうまくいかないのだろうと思うでしょう......

InterruptedException を飲み込まないようにしてください!:

catch(InterruptedException e){
//do nothing
}

実際、例外がキャッチされると、中断されたフラグはクリアされます! したがって、スレッドを再中断して true に設定することを忘れないでください。

catch(InterruptedException e){
    Thread.currentThread.interrupt();
}

詳細な説明については、次のリンクを開いてください: http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

于 2012-09-27T14:34:39.550 に答える
0

あなたの問題address.isReachable(...)は、中断できないことかもしれません。@Mik378が言及したように、スレッドに割り込むと、スレッドに割り込みビットが設定され、いくつかのメソッド(、、Thread.sleep()およびObject.wait()その他)がスローされInterruptedExceptionます。残念ながら中断されるInetAddress.isReachable(...)ことはありません。

アプリケーションを終了できるように、印刷スレッドをすぐに終了させようとしている場合は、それらをデーモン スレッドにすることができます。ここを参照してください:

呼び出し可能なスレッドをデーモンとして作成する

于 2012-09-27T16:09:55.237 に答える
0

PingTaskあなたはURL接続を行っていると思います.connect()呼び出しは割り込み不可能な呼び出しです。

ExecutorService#shutdownNow()は、スレッドを中断することによって即時にシャットダウンする方法を提供しますが、これらのスレッドは中断できないため、追加の利点はありません。

スレッドが割り込みポリシーを定義し、割り込み可能な操作を実行する場合にのみメリットがあります。

于 2012-09-27T14:09:01.457 に答える