使用 IntelliJ IDE、java 1.8、IDE 中的 lang level 6(以及命令提示符下的默认值)。
从命令行 (Windows 7) 编译并运行:
javac -cp . Main.java
java -cp . Main
给出以下代码,我想要做的是关闭应用程序中所有正在运行的线程(如果操作系统或 JVM 为我做的话,也许我不需要这样做)。我有一个线程 MyThread,它又保存它正在管理的线程列表(当被主线程中断时,将向其列表中的每个线程发送一个中断)。
当我运行代码时,我得到输出Keeping busy.
每2秒打印一次。当我按 CTRL-C 时,关闭挂钩运行(我将 println 消息放在那里进行确认),但这就是我看到的所有输出。我从未见过Cancelled.
nr main() 的末尾...所以我还必须假设 Cancel 方法也没有运行。
那么,首先我需要关心这个吗?我可以在 isInterrupted 上循环(在 main 中)并让程序停止吗?如何取消所有子线程?
import java.util.HashMap;
class MyThread extends Thread {}
public class Main
{
private static volatile boolean running = true;
// List of active threads.
private HashMap<String, Thread> threads = new HashMap<String, Thread>();
public static void main(String[] args) throws InterruptedException
{
// Get an instance of the Main class.
Main myApp = new Main();
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
running = false;
}
});
// Loop until system shutdown.
while (running && !Thread.currentThread().isInterrupted())
{
myApp.CreateMyThread();
// In real code, I have a wait() here, rather than the following lines.
System.out.println("Keeping busy.");
Thread.sleep(2000);
}
System.out.println("Cancelled.");
// Kill all threads.
myApp.Cancel();
System.exit(0);
}
private void Cancel()
{
for (Thread t : threads.values())
{
t.interrupt();
}
}
private void CreateMyThread()
{
if (threads.get("mythread") instanceof MyThread)
{
// Already exists.
return;
}
MyThread t = new MyThread();
t.start();
threads.put("mythread", t);
}
}
EDIT:
所以,我改变了我的代码如下。创建了一个包含哈希图的 Threadlist 类,其中的方法使用关键字“synchronized”来添加/删除线程以及取消所有线程。 main 包含此类的静态实例。然后,我的关闭处理程序调用 CancelThreads 方法来关闭所有正在运行的线程。问题:这真的是线程安全的吗?即:在方法上进行同步实际上会阻止一个方法在另一个方法正在进行时运行吗?
import java.util.HashMap;
class MyThread extends Thread {}
class Threadlist
{
// List of threads.
private HashMap<String, Thread> threads = new HashMap<String, Thread>();
public synchronized void AddThread(String name, Thread thread)
{
threads.put(name, thread);
}
public synchronized Thread GetThread(String name)
{
return threads.get(name);
}
public synchronized void CancelThreads()
{
for (Thread t : threads.values())
{
System.out.printf("Killing a thread by the name of '%s'\n", t.getName());
t.interrupt();
}
}
}
public class Main
{
private static volatile boolean running = true;
// List of active threads.
private static Threadlist threads = new Threadlist();
public static void main(String[] args) throws InterruptedException
{
// Get an instance of the Main class.
Main myApp = new Main();
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
threads.CancelThreads();
running = false;
}
});
// Loop until system shutdown.
while (running && !Thread.currentThread().isInterrupted())
{
myApp.CreateMyThread();
// In real code, I have a wait() here, rather than the following lines.
System.out.println("Keeping busy.");
Thread.sleep(2000);
}
System.out.println("Cancelled.");
System.exit(0);
}
private void CreateMyThread()
{
if (threads.GetThread("mythread") instanceof MyThread)
{
// Already exists.
return;
}
MyThread t = new MyThread();
t.start();
threads.AddThread("mythread", t);
}
}
我还开始创建一个 ShutdownHook 类,扩展 Thread,它将通过构造函数接受 main 的线程对象,然后取消 run() 方法中的线程,但我不知道如何更改 main->running 值同时,因此,我的方法上面。