我有一个静态函数,如:
public static void foo()
{
//code follows
System.out.println(Thread.currentThread().getName());
//code follows
}
并且多个线程同时调用此函数。我已经使用
设置了线程的名称Thread.setName(String)
当我执行代码时,print语句将只打印一个线程的名称。如何识别当前执行foo()函数的所有线程的名称?
修改
public class FooThread extends Thread
{
public FooThread(String name)
{
this.setName(name);
}
@Override public void run()
{
//do something
//do something
Main.foo();
}
}
//Main Class
public class Main
{
public static void main(String[] args)
{
for(int i=0;i<6;++i)
{
new FooThread("Thread"+i).start();
}
}
public static void foo()
{
//do something
while(true)
{
//do something
System.out.println(Thread.currentThread().getName());
}
}
}
答案 0 :(得分:4)
您已经显示了调用代码的Thread的名称。代码证明了这一点:
public class Foo2 {
public static synchronized void foo() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
int maxCount = 10;
for (int i = 0; i < maxCount; i++) {
Thread thread = new Thread(new Runnable() {
public void run() {
foo();
}
});
thread.setName("Thread " + i);
thread.start();
long sleepTime = 1000;;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
}
}
返回:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 5
Thread 6
Thread 7
Thread 8
Thread 9
您的问题在于未显示的代码。
同样,要获得有关当前设置实际错误的完整解决方案,请创建并发布与我上面发布的内容类似的sscce。我们知道您可以在线程上调用run()
,直到我们看到并重现您的问题,我认为我们无法完全理解它。
修改强>
关于你的SSCCE:比较下面两种方法的结果,foo1()和foo2()
class FooThread extends Thread {
public FooThread(String name) {
this.setName(name);
}
@Override
public void run() {
// do something
// do something
Main.foo1(); // !! Swap comments
// Main.foo2(); // !! Swap comments
}
}
// Main Class
public class Main {
private static final long SLEEP_TIME = 4;
public static void main(String[] args) {
for (int i = 0; i < 6; ++i) {
new FooThread("Thread" + i).start();
}
}
public static void foo1() {
// do something
while (true) {
// do something
synchronized (Main.class) {
System.out.println(Thread.currentThread().getName());
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {}
}
}
public static void foo2() {
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
}
如果你的while循环不是那么紧,但是用一个简短的Thread.sleep产生CPU,你会看到更多不同的线程在fu附近分享foo。
但同样,您的代码也证明您的线程名称* 是8 正在显示,但您只看到一个名称,因为该线程正在占用CPU。
答案 1 :(得分:1)
另一个选择是获取所有线程堆栈并查找foo()
中的所有线程。除了捕获所需信息之外,这样做没有开销或额外代码的好处。
答案 2 :(得分:0)
如果您只想获取线程数,请使用线程安全计数器来存储线程数。当foo()开始时增加计数器,并在foo()退出时减少计数器。
如果需要获取名称,请使用哈希集(或列表,如果有重复的线程名称)来存储名称:在foo()开始时添加名称,并在foo()退出时删除名称。确保对哈希集的访问是线程安全的。您还需要另一种方法来打印出哈希集的内容,这样您就可以随时调用它来查看执行foo()的线程的名称。
答案 3 :(得分:0)
您可以在方法启动时(在同步块中)将名称放入列表中,然后再将其删除。
List allTheNames = Collections.synchronizedList(new ArrayList<String>());
public void foo() {
allTheNames.add(Thread.currentThread().getName());
// now allTheNames contains all the names of all threads currently in this method.
System.out.println(allTheNames.toString());
allTheNames.remove(Thread.currentThread().getName());
}
当然,如果您在此期间更改线程的名称不起作用,但为什么会这样做?
如果您需要名称的其他信息,也可以存储Thread
。