运行() 中的这个引用在实现Runnable 时可以引用Thread 对象吗?
Can this reference in run() refer to Thread object when implementing Runnable?
抱歉,如果问题不清楚
我正在制作一个简单的多线程程序,它有一个链表来存储除主线程之外创建的所有线程。然后我想发送一些信号来终止主线程,但只有当所有其他线程都关闭时,我打算这样做,当线程关闭时,它将自己从链表中删除,然后主线程将检查该列表是否size == 是否为 null
这是我的代码
public class MainProgram {
//some global static variable
static List<Thread> threadList = new LinkedList<Thread>();
public void main() throws IOException {
ServerSocket serverSocket;
serverSocket = new ServerSocket(1234);
while(true){
if(Shutdown_Handler.shutdown==true){
//wait for all other thread close/terminate
return
}
Socket s = serverSocket.accept();
ClientThread x = new ClientThread(s);
Thread y = new Thread(x);
threadList.add(y);
y.start();
}
}
}
当 Shutdown_Handler.shutdown==true 时,main 将检查 threadList 是否为 null
。问题是我不知道如何让线程从列表中删除自己。正如我所搜索的,对于普通对象,我可以创建这样的方法
public class someObject {
public static void delete(){
if(list.size = null) return;
list.remove(this);
}
}
但是,在线程的情况下,Class 实现 Runnable
所以 this
引用是对象而不是存储在列表中的线程
我建议使用 HashMap
而不是 List
。键可以是线程名称(例如 Thread.getName()
),值将是线程。
Map<String, Thread> threadMap = new HashMap<String, Thread>();
您还应该将此地图创建为同步地图(使用 Collections.synchronizedMap(...)
)
Map<String, Thread> synchronizedMap = Collections.synchronizedMap(threadMap);
现在,无论何时构造线程,都将此 HashMap 传递到其构造函数中,线程可以保存对它的引用。因此,当线程即将终止时,它可以通过使用自己的线程名称作为删除键从 HashMap
中删除自己。
假设ClientThread是一个Runnable,基本代码为:
public class ClientThread implements Runnable {
public void run() {
// do stuff
MainProgram.threadList.remove(Thread.currentThread());
}
}
但是这有几个问题:
将有多个线程在没有正确同步的情况下对列表执行操作。这是不正确的,如果这样做,您可能会遇到间歇性故障。
除非run()
在finally
块中从列表中删除线程,否则异常终止的线程可能不会被删除。
使用全局静态是糟糕的设计。更糟糕的设计是将其公开为裸(非私有)变量。
如果线程数比较大,HashSet<Thread>
效率会更高
抱歉,如果问题不清楚
我正在制作一个简单的多线程程序,它有一个链表来存储除主线程之外创建的所有线程。然后我想发送一些信号来终止主线程,但只有当所有其他线程都关闭时,我打算这样做,当线程关闭时,它将自己从链表中删除,然后主线程将检查该列表是否size == 是否为 null
这是我的代码
public class MainProgram {
//some global static variable
static List<Thread> threadList = new LinkedList<Thread>();
public void main() throws IOException {
ServerSocket serverSocket;
serverSocket = new ServerSocket(1234);
while(true){
if(Shutdown_Handler.shutdown==true){
//wait for all other thread close/terminate
return
}
Socket s = serverSocket.accept();
ClientThread x = new ClientThread(s);
Thread y = new Thread(x);
threadList.add(y);
y.start();
}
}
}
当 Shutdown_Handler.shutdown==true 时,main 将检查 threadList 是否为 null
。问题是我不知道如何让线程从列表中删除自己。正如我所搜索的,对于普通对象,我可以创建这样的方法
public class someObject {
public static void delete(){
if(list.size = null) return;
list.remove(this);
}
}
但是,在线程的情况下,Class 实现 Runnable
所以 this
引用是对象而不是存储在列表中的线程
我建议使用 HashMap
而不是 List
。键可以是线程名称(例如 Thread.getName()
),值将是线程。
Map<String, Thread> threadMap = new HashMap<String, Thread>();
您还应该将此地图创建为同步地图(使用 Collections.synchronizedMap(...)
)
Map<String, Thread> synchronizedMap = Collections.synchronizedMap(threadMap);
现在,无论何时构造线程,都将此 HashMap 传递到其构造函数中,线程可以保存对它的引用。因此,当线程即将终止时,它可以通过使用自己的线程名称作为删除键从 HashMap
中删除自己。
假设ClientThread是一个Runnable,基本代码为:
public class ClientThread implements Runnable {
public void run() {
// do stuff
MainProgram.threadList.remove(Thread.currentThread());
}
}
但是这有几个问题:
将有多个线程在没有正确同步的情况下对列表执行操作。这是不正确的,如果这样做,您可能会遇到间歇性故障。
除非
run()
在finally
块中从列表中删除线程,否则异常终止的线程可能不会被删除。使用全局静态是糟糕的设计。更糟糕的设计是将其公开为裸(非私有)变量。
如果线程数比较大,
HashSet<Thread>
效率会更高