2016-02-16 2 views
0

У меня есть класс (extends Thread), из которого я запускаю несколько потоков.Получить количество активных потоков в java

Вот класс:

public class Abc extends Thread{ 
    private String key; 
    public void run(){} 
} 

Теперь я хочу знать, сколько активных потоков есть этого класса на основе стоимости key.

например. Я установить значение ключа, как «X» в 10 потоков и «Y» в 15. Я хочу, чтобы создать карту:

map<String, int> :: {"X"=10, "Y"=15} 

Как я могу это сделать?

EDIT:

Этот Map<> будет храниться в Execute класса, который создает нити. Это не имеет никакого отношения к Abc.

+1

http://stackoverflow.com/a/11537026/3365426 –

+0

я видел. Он не говорит, как классифицировать на основе некоторой ценности. – vish4071

+0

Ваш вопрос не совсем ясен. Какие значения должны иметь ваши «ключи»? Является ли карта частью вашей нити? напишите пример кода о том, как вы хотите изменить 'key' в зависимости от карты – adranale

ответ

3

Вы можете увеличивать счетчик при запуске задачи и уменьшать ее, когда она заканчивается.

Что-то вроде

public void run() { 
    AtomicInteger counter = counterMap.computeIfAbsent(key, k -> new AtomicInteger()); 
    counter.incrementAndGet(); 
    try { 
     doRun(); 
    } finally { 
     counter.getAndDecrement(); 
    } 
} 
0

Сделайте key статическими, так что он будет держать свои значения между потоками.

+1

Существует несколько значений 'key'. Он не может быть статичным. – vish4071

0

Вы можете сделать что-то вроде этого:

static HashMap<String, Integer> threadsCount = new HashMap<String, Integer>(); 
String key; 

public Abc(String key) { 
    this.key = key; 
    synchronized (threadsCount) { 
     if (threadsCount.containsKey(key)) { 
      threadsCount.put(key, threadsCount.get(key) + 1); 
     } else { 
      threadsCount.put(key, 1); 
     } 
    } 
} 

и уменьшаем счетчик, когда нить заканчивается:

@Override 
public void run() { 
    .... 
    synchronized (threadsCount) { 
     if (threadsCount.containsKey(this.key)) { 
      threadsCount.put(key, threadsCount.get(this.key) - 1); 
     } 
    } 
} 

@ vish4071, основанный на ваш комментарий, я думаю, что лучшее решение для вашего прецедент будет это:

public class Abc extends Thread { 
    String key; 

    public Abc(String key) { 
     this.key = key; 
    } 

    public String getKey(){ 
     return key; 
    } 
    .... 
} 

И получить количество:

HashMap<String, Integer> threadsCount = new HashMap<String, Integer>(); 

for (Thread t : Thread.getAllStackTraces().keySet()) { 
    if (t instanceof Abc) { 
     if (t.getState() != Thread.State.TERMINATED) { 
      String key = ((Abc)t).getKey(); 
      if (threadsCount.containsKey(key)) { 
       threadsCount.put(key, threadsCount.get(key) + 1); 
      } else { 
       threadsCount.put(key, 1); 
      } 
     } 
    } 
} 
+0

Почему я должен использовать 'synchronized'? – vish4071

+0

@ vish4071 Чтобы убедиться, что 'threadsCount.containsKey (key)' возвращает 'true', даже если вы создаете несколько потоков одновременно с использованием того же' ключа'. – Titus

+0

Это прекрасный ответ, но он не подходит для моего использования. Что, если по какой-либо причине (системный уровень), какой-то поток просто перестает работать (сбой)? Потому что потоки полностью работают с другим процессом. Кроме того, мне придется закрыть потоки, и те, которые работают, будут работать вечно. – vish4071

0
public class Abc extends Thread{ 
     private static Map<String, Integer> map = new ConcurrentHashMap<>(); 
     private String key; 
     public void run(){ 
      synchronized (key) { 
       Integer current = map.get(key); 
       if(null == current) { 
        map.put(key, 1); 
       } else { 
        map.put(key, current +1); 
       } 
      } 

      //Run execution code here. 
      synchronized (key) { 
       Integer current = map.get(key); 
       map.put(key, current -1); 
      } 
     } 
    } 
Смежные вопросы