gpt4 book ai didi

java - 在Runnable的整个生命周期中,Thread.currentThread()方法是否总是返回相同的对象?

转载 作者:行者123 更新时间:2023-12-03 13:16:35 27 4
gpt4 key购买 nike

我一直在我的Runnable#run()方法中使用Thread#currentThread()获取对当前正在执行的线程的引用。由于Runnable可以在一个Executor中并行运行多个相似的副本一段时间,因此它会始终返回相同的Thread对象,还是可以在Runnable的整个生命周期中进行更改?
因此,基本上,当我运行这种Runnable一段时间后,是否会遇到问题?

class MyRunnable implements Runnable {

@Override
public void run() {
Thread current = Thread.currentThread();

while(!current.isInterrupted()) {
try {
// some processing that can take a while...
} catch(InterruptedException e) {
// some cleanup
current.interrupt();
}
}

// goodbye
}
}

最佳答案

您问的是错误的问题。只要在同一线程中执行代码,表达式Thread.currentThread()就会求值到表示该线程的同一对象。
但这与Runnable的生存期无关。 Runnable(或更确切地说是实现runnable的类的实例)是一个普通对象,可以独立于线程使用。最值得注意的是,多个线程可以执行同一对象的run()方法:

class MyRunnable implements Runnable {
@Override
public void run() {
Thread current = Thread.currentThread();
System.out.println(current);
}
}

MyRunnable r = new MyRunnable();

new Thread(r).start();
new Thread(r).start();
new Thread(r).start();
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-2,5,main]
但是,这并不意味着假设为特定的执行获取相同的 Thread实例是错误的。
要构建您的示例代码,请执行以下操作:
class MyRunnable implements Runnable {
@Override
public void run() {
Thread current = Thread.currentThread();
while(!current.isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
current.interrupt();
}
}
System.out.println(current+" has been interrupted, exiting");
}
}

MyRunnable r = new MyRunnable();

Thread[] threads = { new Thread(r), new Thread(r), new Thread(r) };

for(Thread t: threads) t.start();
for(Thread t: threads) try {
Thread.sleep(400);
System.out.println("going to interrupt "+t);
t.interrupt();
t.join();
}
catch (InterruptedException ex) {
throw new AssertionError(ex);
}
将正确打印:
going to interrupt Thread[Thread-0,5,main]
Thread[Thread-0,5,main] has been interrupted, exiting
going to interrupt Thread[Thread-1,5,main]
Thread[Thread-1,5,main] has been interrupted, exiting
going to interrupt Thread[Thread-2,5,main]
Thread[Thread-2,5,main] has been interrupted, exiting
因此, Thread.currentThread()将在线程的整个生命周期(从该线程中调用)返回相同的对象,而不是可运行的生命周期,但这正是您想要的。您也可以使用
class MyRunnable implements Runnable {
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
System.out.println(Thread.currentThread()+" has been interrupted, exiting");
}
}
达到同样的效果。但是请记住,第一个示例有效,因为线程已存储在局部变量中。如果要将线程存储到对象的字段中,则必须确保多个线程并不会同时使用该对象(因为在多个线程使用共享可变状态时,您始终要格外小心)。

关于java - 在Runnable的整个生命周期中,Thread.currentThread()方法是否总是返回相同的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64048741/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com