Есть ли способ отличить основной поток от всех потоков, которые он порождает? - PullRequest
5 голосов
/ 30 января 2012

Я знаю, что функция getName() в главном потоке вернет строку main, но это можно изменить с помощью setName().

. Есть ли способ всегда определять основной потокзаявление?

Ответы [ 3 ]

8 голосов
/ 30 января 2012

Одна из возможностей - позвонить Thread.currentThread() в начале main() и удерживать ссылку.

5 голосов
/ 30 января 2012

Похоже, что основной поток имеет 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();
    }
}    
2 голосов
/ 30 января 2012

Исходя из вашего вопроса и ваших ответов на комментарии, я бы предложил следующие 2 подхода:

  1. Поместите все запросы в очередь событий, и главный поток будет принимать запросы из очереди запросов на вызовметод, о котором вы говорите.В этом случае должен быть контракт, который любой другой метод, желающий получить доступ к методу, о котором вы говорите, может сделать это только через очередь событий (та же идея, что и EDT).

  2. Поместитьдополнительный параметр в методе, который вы хотите, чтобы он вызывался только main, чтобы действовать как токен. Внутри метода проверьте, является ли токен корректным (только main будет иметь его / будет знать его). Если он правильный, тогда продолжайте. Иначевернуть ложь.Конечно, если вам разрешено сделать такую ​​модификацию

...