0

jToggleButton を使用して、次のように生成されたスレッドを停止したいと考えています。スレッドは、ファイルのフォルダーを監視するために使用されます。私はたくさん試し、たくさん検索しましたが、成功しません。生成されたスレッドを停止するための解決策を提案してください。jToggleButton を押した後でも、Netbeans デバッグでスレッドがアクティブに表示されます。停止するための揮発性条件を試しました。参考までに、スレッドを開始および停止するための jToggle ボタンがあります。

コードは Netbeans によって生成されるため、余分なコードがいくつかありますが、jToggleActionListener 内のコードと別のクラスのコードにのみ注目してください。ご協力ありがとうございます。

package threadnames;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level; 
import java.util.logging.Logger;
public class NewJFrame extends javax.swing.JFrame {

    public NewJFrame() {
        initComponents();
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jToggleButton1 = new javax.swing.JToggleButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jToggleButton1.setText("Stop");
    jToggleButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jToggleButton1ActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(84, 84, 84)
            .addComponent(jToggleButton1)
            .addContainerGap(142, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(25, 25, 25)
            .addComponent(jToggleButton1)
            .addContainerGap(28, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                               
    ExecutorService exec = Executors.newCachedThreadPool();
    if (this.jToggleButton1.isSelected()) {
        try {
            // TODO add your handling code here:
            Path home = Paths.get(System.getProperty("user.dir"));
            WatchService watcher;

            watcher = home.getFileSystem().newWatchService();

                home.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
            Runnable task = new FileWatch(watcher);
            exec.submit(task);
            boolean terminated;
            terminated = exec.awaitTermination(1, TimeUnit.SECONDS);

            if (terminated) {
                System.out.println("All tasks completed.");
            } else {
                System.out.println("Some tasks are still running.");
            }
        } catch (IOException | InterruptedException ex) {
            Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else {
        exec.shutdownNow();
    }
}                                              

public static void main(String args[]) {
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info    javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;


            }
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException |        javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class
                .getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
}
// Variables declaration - do not modify                     
public javax.swing.JToggleButton jToggleButton1;
// End of variables declaration                   
}

run() の他のクラスは次のとおりです。

package threadnames;

import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.Watchable;

final class FileWatch implements Runnable {

private final WatchService watcher;

FileWatch(WatchService watcher) {
    this.watcher = watcher;
}

@Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        WatchKey key;
        try {
            key = watcher.take();
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
            break;
        }
        Watchable dir = key.watchable();
        System.out.println(dir);
        for (WatchEvent<?> evt : key.pollEvents()) {
            System.out.println("   " + evt.context());
        }
    }
}
}
4

4 に答える 4

2

1 つの方法は、 aをstopに設定するメソッドを使用することです。volatile booleantrue

public class HelloRunnable implements Runnable {
  private volatile boolean stop = false;

  public void run() {
    if (!stop) {
      System.out.println("Hello from a thread!");
    }
  }

  public void stop() {
    stop = true;
  }

  public static void main(String args[]) {
    for (int i = 0; i < 5; i++) {
      HelloRunnable hr = new HelloRunnable();
      new Thread(hr).start();
      hr.stop();
    }
  }
}

スレッドがブロックされている可能性がある場合は、スレッドを中断するように手配できますが、もちろん、スレッドがブロックされていない可能性があり、単にビジーである可能性があるため、スレッドが中断されるとは限りません。

public class HelloRunnable implements Runnable {
  private volatile boolean stop = false;
  private volatile Thread thread = null;

  public void run() {
    thread = Thread.currentThread();
    if (!stop) {
      System.out.println("Hello from a thread!");
    }
  }

  public void stop() {
    stop = true;
    if ( thread != null ) {
      thread.interrupt();
    }
  }

  public static void main(String args[]) {
    for (int i = 0; i < 5; i++) {
      HelloRunnable hr = new HelloRunnable();
      new Thread(hr).start();
      hr.stop();
    }
  }
}

この最後の手法は、WatchService.poll(...)またはWatchService.take()を使用している場合にも機能するはずです。

また、スレッドがほとんどの IO プロセスでビジーな場合は、スレッドを中断する必要があります。

于 2013-09-10T15:03:20.557 に答える
1

Thread.stop()メソッドはありますが、安全ではないため廃止されました。

非推奨のメソッドを使用する代わりに、変数を変更して、ターゲット スレッドの実行を停止する必要があることを示すことができます。

于 2013-09-10T14:57:55.007 に答える
1

flagメソッド内でsome を使用して、runメソッドを終了するかどうかを確認できます。これにより、runメソッドを間接的に終了できます。他の方法でスレッドを停止することは、現時点ではお勧めできません。リンクを見る

于 2013-09-10T15:01:05.733 に答える