多线程应用程序中的 ShutDownHook

发布于 2024-12-17 10:59:38 字数 3027 浏览 2 评论 0原文

我有一个应用程序,它的主要方法生成一百个线程(假设我们模拟一百个帐户)。我正在试验它,我希望它在用 Control-C 中断时只打印终止。

我读到您可以使用 ShutDownHooks 来做到这一点,所以我在我的 main 方法中添加了以下内容:

Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                             System.out.println("Terminating");
                        }
        });

但是,当我运行它时,没有任何内容被打印。

您能否就我出错的地方提供一些指导(所有线程都在 for 循环中声明并从调用其 start 方法开始)?

问候, 乔治

编辑:请参阅下面的代码:

银行类:

public class Bank {
 private final double[] accounts;
   public Bank(int n, double initialBalance) {
    accounts = new double[n];
    for (int i=0; i < accounts.length;i++) {
        accounts[i] = initialBalance;
    }
}
    public double getTotalBalance() {
        double sum = 0.0;
        for (int i=0; i < accounts.length; i++) {
            sum += accounts[i];
        }
        return sum;
    }
    public synchronized void transfer(int fa, int ta, double amt) throws InterruptedException{
        System.out.print(Thread.currentThread());
        if (accounts[fa] < amt){
                        wait();
                    }
        accounts[ta] -= amt;
        System.out.println("Transfer of amount: " + amt + " from: " + fa + " Transfer to: " + ta);
        accounts[fa] += amt;
        System.out.println("Total Balance: " + getTotalBalance());
        notifyAll();

}
public int size() {
    return accounts.length;
}
public double[] getAccounts(){
    return accounts;
}

}

BankTest类:

public class BankTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
            Bank b = new Bank(100,1000);
    int i;
        long timeStart = System.currentTimeMillis();
        long j = System.currentTimeMillis();





            for (i=0; i < b.size(); i++) {
        TransferRunnable tr = new TransferRunnable(b, i, 1000,j);
        Thread t = new Thread(tr);
        t.start();

    }
           Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
                         System.out.println("Terminating");
                    }
    });


        }


    }

TransferRunnable类:

public class TransferRunnable implements Runnable {
private Bank b;
private int fromAccount;
private double maxAmount;
private final int DELAY = 40;
private long timeStart;
public TransferRunnable(Bank b, int from, double max, long timems) {
    this.b = b;
    fromAccount = from;
    maxAmount = max;
        timeStart = timems;
}
@Override
public void run() {

        try {
        while (true) {
            int ta = (int) (b.size() * Math.random());
            double amount =  maxAmount * Math.random();
                    double[] acc = b.getAccounts();
                    b.transfer(fromAccount,ta,amount);
            Thread.sleep((int) (DELAY*Math.random()));
        }
    }
        catch (InterruptedException e) {

        }

    }

}

I have an application which in its main method spawns a hundred threads (let's say we simulate a hundred accounts). I am experimenting with it and I would like it to just print terminating when intterupted with Control-C.

I read you can do that with ShutDownHooks so I added the following in my main method:

Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                             System.out.println("Terminating");
                        }
        });

However, when I run it nothing gets printed.

Could you please offer me some guidance as to where I am going wrong (all threads are declared in a for loop and start with invoking their start method)?

Regards,
George

EDIT: Please see below for the code:

Bank Class:

public class Bank {
 private final double[] accounts;
   public Bank(int n, double initialBalance) {
    accounts = new double[n];
    for (int i=0; i < accounts.length;i++) {
        accounts[i] = initialBalance;
    }
}
    public double getTotalBalance() {
        double sum = 0.0;
        for (int i=0; i < accounts.length; i++) {
            sum += accounts[i];
        }
        return sum;
    }
    public synchronized void transfer(int fa, int ta, double amt) throws InterruptedException{
        System.out.print(Thread.currentThread());
        if (accounts[fa] < amt){
                        wait();
                    }
        accounts[ta] -= amt;
        System.out.println("Transfer of amount: " + amt + " from: " + fa + " Transfer to: " + ta);
        accounts[fa] += amt;
        System.out.println("Total Balance: " + getTotalBalance());
        notifyAll();

}
public int size() {
    return accounts.length;
}
public double[] getAccounts(){
    return accounts;
}

}

BankTest Class:

public class BankTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
            Bank b = new Bank(100,1000);
    int i;
        long timeStart = System.currentTimeMillis();
        long j = System.currentTimeMillis();





            for (i=0; i < b.size(); i++) {
        TransferRunnable tr = new TransferRunnable(b, i, 1000,j);
        Thread t = new Thread(tr);
        t.start();

    }
           Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
                         System.out.println("Terminating");
                    }
    });


        }


    }

TransferRunnable Class:

public class TransferRunnable implements Runnable {
private Bank b;
private int fromAccount;
private double maxAmount;
private final int DELAY = 40;
private long timeStart;
public TransferRunnable(Bank b, int from, double max, long timems) {
    this.b = b;
    fromAccount = from;
    maxAmount = max;
        timeStart = timems;
}
@Override
public void run() {

        try {
        while (true) {
            int ta = (int) (b.size() * Math.random());
            double amount =  maxAmount * Math.random();
                    double[] acc = b.getAccounts();
                    b.transfer(fromAccount,ta,amount);
            Thread.sleep((int) (DELAY*Math.random()));
        }
    }
        catch (InterruptedException e) {

        }

    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

命比纸薄 2024-12-24 10:59:38

当我运行它时它会被打印。不过,您可以将 System.out.flush(); 添加到 run() 方法的末尾,这可以确保立即打印输出。

It gets printed when I run it. You could add System.out.flush(); to the end of the run() method though, this makes sure that the output is printed immediately.

樱花坊 2024-12-24 10:59:38

正如其他人所说,这应该可行。您使用什么操作系统? CTRL+C 可能会完全终止进程,而不是要求其关闭(例如 SIGKILL 与 SIGINT)。您可以验证您正在向 Java 进程发送哪个信号吗?

最后,作为最后的手段,您可以尝试以下 Java:

if (FileDescriptor.out.valid()) {
    FileDescriptor.out.sync();
}

不过我怀疑这不会有任何区别!

as others have said, this should just work. What OS are you using? It might be that CTRL+C is killing the process completely rather than asking it to shutdown (eg SIGKILL vs SIGINT). Can you verify which signal you're sending the Java process?

Finally, as a last resort you could try the following bit of Java:

if (FileDescriptor.out.valid()) {
    FileDescriptor.out.sync();
}

I suspect that this won't make any difference though!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文