Thread类中的方法与使用Thread.currentThread()的方法之间有什么区别?

huangapple go评论77阅读模式
英文:

Difference between methods from Thread class and methods used with Thread.currentThread()?

问题

我想从currentThread()方法的文档开始:

  • 返回对当前正在执行的线程对象的引用。
  • @return 当前正在执行的线程。

有了这个了解,就能理解为什么诸如join()isAlive()getName()isInterrupted()等方法会像这样被调用,例如Thread.currentThread().join

我的问题是,为什么我们在调用诸如sleep()yield()interrupted()等方法时不需要currentThread这个前缀呢?例如,如何在没有实例的情况下,静态调用Thread.sleep() 等方法能够准确地知道我们要“定位”的线程实例?

英文:

I want to start with doc from method currentThread():

> * Returns a reference to the currently executing thread object.
> * @return the currently executing thread.

Now knowing this, it makes sense that methods such as join(), isAlive(), getName(), isInterrupted() etc. are called like this for example Thread.currentThread().join.

My question is how we don't need currentThread prefix to call methods such as sleep(), yield(), interrupted() etc? How can static call for example Thread.sleep() know exactly what thread instance are we 'targeting' when there is no instance?

答案1

得分: 5

如何使静态调用(例如Thread.sleep())在没有实例的情况下准确地知道我们正在“targeting”哪个线程实例?

它们会针对当前正在执行的线程进行操作。

Thread的文档中可以找到:

使当前正在执行的线程休眠

yieldinterrupted 等的文档也提到它们会影响当前线程。

关于 joingetName 等的评论:

join 设为静态是没有意义的。如果这样做,你只能等待当前线程,这会导致立即死锁。你会让当前线程等待它自己。join 必须是非静态的,这样你才能告诉它要等待哪个线程(好吧,你可以有一个 static join(Thread threadToJoin),但那会很麻烦)。

sleepyield 只有在静态情况下才有意义 - 你永远不会告诉另一个线程去休眠或者让出执行(你不知道另一个线程正在做什么 - 它可能没有处于合适的状态来休眠或让出执行)。你只会让自己进入休眠状态。

你在评论中提到的其他方法也可能有静态变体,但将它们设置为非静态更有意义,因为它们提供了关于调用它们的特定Thread对象的信息。你可能会注意到 interruptedisInterrupted 一个是静态的,一个是非静态的,因此在某些情况下同时提供两种方式是有意义的。是否值得拥有一个静态的 getCurrentThreadName() 方法呢?可能不值得。我们并不经常查找线程名称,但检查是否中断是一种非常常见的操作,因此不必编写 Thread.currentThread().isInterrupted() 这样的代码会比维护两种方法更加方便。

英文:

> How can static call for example Thread.sleep() know exactly what thread instance are we 'targeting' when there is no instance?

They target the currently executing thread.

From the docs for Thread:

> Causes the currently executing thread to sleep

The documentation for yield and interrupted etc also mention that they affect the current thread.

Regarding the comments about join, getName etc:

It doesn't make sense to make join static. If you did, the only thread you could join would be the current thread, which would immediately deadlock. You would be asking the current thread to wait for itself. join has to be non-static so you can tell it which thread to wait for (OK, you could have static join(Thread threadToJoin) but that's pretty cumbersome).

Sleep, and yield only make sense statically - you would never tell another thread to sleep or yield (you don't know what the other thread is doing - it might not be in a sensible state to sleep or yield). You only ever want to put yourself to sleep.

The other methods you mention in the comments could conceivably have static variants, but it makes more sense for them to be non-static because they provide information about the specific Thread object they are called on. You may notice that interrupted and isInterrupted are static and non-static, respectively, so there are cases where it makes sense to provide both. Is it worth having a static getCurrentThreadName() method? Probably not. We don't look for thread names very often, but checking for interruption is a very common operation so the convenience of not having to say Thread.currentThread().isInterrupted() outweighs the cost of maintaining two methods.

答案2

得分: 1

因为sleep()不是一个线程应该能够对另一个线程执行的操作。

Thread.currentThread()返回对Thread类的一个实例的引用。从调用者的角度来看,它是一个特殊的实例(即调用该函数的Thread),但从语言的角度来看,它并没有什么特别之处。它只是一个线程。

这意味着,如果你可以调用Thread.currentThread().foo(),那么你也可以调用someOtherThread.foo()

即使允许你调用someOtherThread.sleep(),这仍然是一个非常糟糕的想法。这就是为什么他们将sleep()作为一个static方法,它在调用线程上 隐式地 运行。


我的问题是为什么我们不需要currentThread作为前缀...

好的,我只是提供一点建议,如果你将currentThread()看作一种_前缀_,那么我建议你在深入编写多线程程序之前花更多时间学习Java语言的基础知识。

英文:

> why is for example Thread.sleep() written and not Thread.currentThread().sleep()

Because sleep() is not something that one thread should be able to do to a different thread.

Thread.currentThread() returns a reference to an instance of the Thread class. It's a special instance from the caller's point of view (i.e., it happens to be the Thread that called the function,) but from the language point of view, there's nothing special about it at all. It's just a thread.

That means, if you can call Thread.currentThread().foo(), then you can call someOtherThread.foo().

Even if you were allowed to call someOtherThread.sleep(), it would be a very bad idea. That's why they made sleep() a static method that implicitly operates on the calling thread.


> My question is how we don't need currentThread prefix ...

OK, this is just my two cents worth, but if you think of currentThread() as some kind of a prefix, then I would advise you to spend more time learning the basics of the Java language before you dive into writing multi-threaded programs.

huangapple
  • 本文由 发表于 2020年9月17日 09:06:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63929869.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定