2

在主题中,我是否正确关闭了这些同时线程?

我分配了一个 volatile 字段并在 while 循环中反复检查它。

是否有替代方法(例如使用 synchronize 或 wait() 方法),请告诉我。

编辑我编辑了代码。有什么方法可以通过 isAlive(); 的不同方法检查 Thread 是否还活着?也许:

boolean isAlive(){
    return running;
}

import javax.swing.JOptionPane;

public class Wat extends Thread {
    private char c;
    private int interv;
    private volatile boolean running = true;
    Object synchObj;

    public Wat(char c, int interv) {
        this.c = c;
        this.interv = interv;
        synchObj = new Object();
    }

    public void run() {
        while (running) {
            synchronized (synchObj) {
                try {
                    showChar(c);
                    synchObj.wait(interv * 100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public synchronized static void showChar(char c) {
        System.out.println(c);
    }

    public void shutdown() {
        running = false;
        synchronized (synchObj) {
            synchObj.notify();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Wat w1 = new Wat('A', 3);
        Wat w2 = new Wat('B', 4);
        Wat w3 = new Wat('C', 5);
        w1.start();
        w2.start();
        w3.start();
        Object[] options = { "Shutdown A", "Shutdown B", "Shutdown C" };
        int option;
        while (w1.isAlive() || w2.isAlive() || w3.isAlive()) {
            option = JOptionPane.showOptionDialog(null,
                    "Which one would you like to shut?", "Threads",
                    JOptionPane.YES_NO_CANCEL_OPTION,
                    JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
            switch (option) {
            case JOptionPane.YES_OPTION:
                w1.shutdown();
                break;
            case JOptionPane.NO_OPTION:
                w2.shutdown();
                break;
            case JOptionPane.CANCEL_OPTION:
                w3.shutdown();
                break;
            }
            Thread.sleep(1);
        }
    }
}
4

3 回答 3

4

您的代码可能会正常工作,但 Thread.sleep 不是很优雅。我会按照这些思路做一些事情,调用 shutdown() 方法来退出线程

 Object synchObj = new Object();

 public void run() {
    while (running) {
      synchronized (synchObj) {
         try {
            System.out.println(new Date());
            synchObj.wait(5000);
         } catch (InterruptedException e) {
             // error handling
         }
      }
    }
 }

 public void shutdown() {
    running = false;
    synchronized (synchObj) {
        synchObj.notify();
    }
 }


public static void main(String[] args) throws InterruptedException,
        IOException {
    ThreadTest test = new ThreadTest();
    test.start();
    BufferedReader tReader = new BufferedReader(new InputStreamReader(
            System.in));
    tReader.readLine();
    test.shutdown();
}

编辑添加测试代码

于 2012-11-06T09:24:40.880 回答
3

是的,您正确地关闭了线程。唯一的评论是您在这里打破了封装,因为running直接访问了标志。我建议您添加shutdown()将此标志更改为false.

编辑。

我刚刚注意到您sleep()在循环内调用。在大多数情况下,这确实是不好的做法。你可能应该打电话给wait(timeout). 在这种情况下,您的shutdown()方法会将标志更改为false,然后notify()在同一监视器上调用。这将导致您的线程立即退出。

于 2012-11-06T09:19:11.143 回答
0

看起来程序很完美,使用 volatile 布尔变量并使其为假。

同步只需要多线程访问。您可以使用等待代替睡眠,它具有对象访问而不是静态睡眠,也可以随时中断等待。

于 2012-11-06T09:28:24.960 回答