有啥方法可以区分主线程和它产生的任何线程吗?
Posted
技术标签:
【中文标题】有啥方法可以区分主线程和它产生的任何线程吗?【英文标题】:Is there any way to distinguish the main Thread from any Threads that it spawns?有什么方法可以区分主线程和它产生的任何线程吗? 【发布时间】:2012-02-22 04:54:48 【问题描述】:我知道主线程上的getName()
函数会返回字符串main
,但这可以用setName()
改变。
有什么方法可以始终确定应用程序的主线程吗?
【问题讨论】:
【参考方案1】:一种可能性是在main()
的开头调用Thread.currentThread()
,并保留引用。
【讨论】:
比如说我在写一个框架,我有一个静态方法,我只希望主线程能够执行? 听起来你好像遇到了设计问题 ;-) 如果你必须有这个,我会简单地记录它(就像大多数 GUI 框架记录了你只能从事件调度线程)。 如果你看看 android API。我相信只有主线程/活动可以执行 UI 更改。可以将消息传递回主线程,请求它进行更改,但如果有其他任何尝试,则会引发异常。 @Jivings:如果您的情况类似于 GUI 框架,那么您的问题与您描述的略有不同。您不需要识别主线程,您需要识别执行特定代码的线程(GUI 框架中的消息循环)。 @axtavt 我认为这将是主线程,但也许不是。【参考方案2】:似乎主线程的 id 为1
,如Thread.getId()
所示:
class test
public static boolean isMainThread()
return Thread.currentThread().getId() == 1;
public static void main(String[]args)
System.out.println(isMainThread());
new Thread( new Runnable()
public void run()
System.out.println(isMainThread());
).start();
我不确定它是规范的一部分还是特定于实现的功能。
一种更便携的方式是这样的:
class test
static long mainThreadId = Thread.currentThread().getId();
public static boolean isMainThread()
return Thread.currentThread().getId() == mainThreadId;
public static void main(String[]args)
System.out.println(isMainThread());
new Thread( new Runnable()
public void run()
System.out.println(isMainThread());
).start();
需要注意的是,mainThreadId
必须位于由主线程加载的类中(例如,包含 main
方法的类)。例如,这不起作用:
class AnotherClass
static long mainThreadId = Thread.currentThread().getId();
public static boolean isMainThread()
return Thread.currentThread().getId() == mainThreadId;
class test
public static void main(String[]args)
//System.out.println(isMainThread());
new Thread( new Runnable()
public void run()
System.out.println(AnotherClass.isMainThread());
).start();
【讨论】:
不错的一个。我猜这将是特定于实现的,因为 Thread 存储结构不是由 JVM 规范定义的。 很公平。从好的方面来说,appears 这种行为是java.lang.Thread
源代码的一部分,所以它不是 JVM 内部的。
我不知道这种方法。看起来你的答案是正确的,然后弗拉德!虽然功能可以被实现覆盖,但假设它不会被覆盖是合理的!
@Vlad:是什么让您认为 java.lang.Thread 的源代码不是特定于实现的?
@Jivings:不,假设未记录的行为在不同的 JavaVM 实现或版本之间不会改变或保持一致是不合理的。【参考方案3】:
根据您的问题和您对 cmets 的回答,我建议以下两种方法:
将所有请求放到一个事件队列中,主线程将接受 来自请求队列的请求以调用您正在谈论的方法 关于。在这种情况下,必须有任何其他方法的合同 想要访问您正在谈论的方法只能这样做 通过事件队列(与 EDT 相同)。
在您希望被调用的方法中放置一个额外的参数
main 仅充当令牌。在方法内部检查令牌是否
正确(只有main
会拥有它/知道它)。如果它是正确的,那么
继续。否则返回false。当然如果允许你做这样的修改
【讨论】:
谢谢,这似乎是一个合理的解决方案。以上是关于有啥方法可以区分主线程和它产生的任何线程吗?的主要内容,如果未能解决你的问题,请参考以下文章
在java层用线程调用native方法 jni能回调主线程的方法吗?