找到最后一个活动的线程来打印一些东西

时间:2015-07-29 03:55:50

标签: java multithreading

我有一个Thread类,它假设读取文本文件并计算文本文件中的单词数。运行调用如下:

/**
 * Executes and counts # of words in textfile
 */
public void run()
{
    lock.readLock().lock();
    try
    {
        while(in.hasNext())
        {
            String tmp = in.next();
            character ++;
            totalCharacter++;   
        }
        System.out.println(input + ": " + character);
        /**
        if(Thread.activeCount() == 0)
        {
            System.out.println("Total characters in all textfiles: " + totalCharacter);
        }
        */
    }
    finally
    {
        lock.readLock().unlock();
    }

}

我无法弄清楚如何找到最后一个运行线程,这样我就可以打印出每个调用的文本文件中的字符总数。我尝试使用注释部分Thread.activeCount()== 0来做到这一点,但这不起作用。

有关在什么/哪里找到最后一个正在运行的线程来打印所有文本文件中的单词总数的建议?

主函数看起来像这样(我使用命令行参数输入信息):

public static void main(String[] args) throws FileNotFoundException, InterruptedException
{
    for(int i = 0 ; i < args.length ; i++)
    {
        Thread2 wct = new Thread(args[i]);
        wct.start();
    }

}

3 个答案:

答案 0 :(得分:2)

您可以尝试使用线程ID来跟踪您在main方法中创建的各种线程:

public static void main(String[] args) throws FileNotFoundException, InterruptedException {
    for (int i = 0 ; i < args.length ; i++) {
        Thread2 wct = new Thread(args[i]);
        wct.start();
        System.out.println("Thread #" + i + " has id " + wct.getId());
    }
}

我添加的System.out语句可以让你将线程的数量与其运行的id相关联,以便以后进行比较。

然后在你的线程run()方法中,你也可以在线程执行完毕之前打印出当前正在运行的线程的id:

public void run() {
    lock.readLock().lock();
    try {
        while(in.hasNext()) {
            String tmp = in.next();
            character ++;
            totalCharacter++;   
        }
        System.out.println(input + ": " + character);
    }
    finally {
        lock.readLock().unlock();
        long threadId = Thread.currentThread().getId();
        // print out id of this Thread
        System.out.println("Thread with id " + threadId + " is about to finish executing");
    }
}

答案 1 :(得分:1)

我写了一个小程序:

package ant.test;

import java.util.Random;

public class ThreadTest implements Runnable {

    private int msec;

    public ThreadTest(int msec) {
        this.msec = msec;
    }

    public static void main(String[] args) {
        Random r = new Random();
        for(int i = 0; i < 5; i++)
            new Thread(new ThreadTest(r.nextInt(1000))).start();
    }

    @Override public void run() {
        System.out.println("Thread.activeCount = " + Thread.activeCount() + " activeThead = " + Thread.currentThread().getId());
        try {
            Thread.sleep(msec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread.activeCount(exiting) = " + Thread.activeCount() + " activeThead = " + Thread.currentThread().getId());
        if(Thread.activeCount() == 2) {
            Thread[] tarray = new Thread[5];
            int nThreads = Thread.enumerate(tarray);
            for (int i = 0; i < nThreads; i++) {
                System.out.println(tarray[i].getName());
            }
        }
    }
}

结果是,当执行最后一个线程时,活动线程的数量是两个。当前线程和DestroyJavaVM线程。请参阅以下输出:

Thread.activeCount = 4 activeThead = 8
Thread.activeCount = 4 activeThead = 9
Thread.activeCount = 5 activeThead = 10
Thread.activeCount = 6 activeThead = 11
Thread.activeCount = 6 activeThead = 12
Thread.activeCount(exiting) = 6 activeThead = 8
Thread.activeCount(exiting) = 5 activeThead = 11
Thread.activeCount(exiting) = 4 activeThead = 12
Thread.activeCount(exiting) = 3 activeThead = 10
Thread.activeCount(exiting) = 2 activeThead = 9
Thread-1
DestroyJavaVM

那就是说,检查activeThreadCount在我看来并不是正确的解决方案。您可能希望使用某种计数信号量来实现您的目标。

答案 2 :(得分:0)

以下解决方案基于CountDownLatch:

  Class myRunnable implements Runnable
 {
     CountDownLatch cdl;

     public myRunnable(CountDownLatch cd1)
     {
      this.cd1 = cd1;
     }

     public void run()
     {
        lock.readLock().lock();
        try
        {
           // Your code logic

            cdl.countDown();

            if(cd1.getCount() == 0)
                System.out.println("Total characters in all textfiles: " + totalCharacter);                
        }
        finally
            lock.readLock().unlock();
     }
  }

 Class Demo
 {
  public static void main(String[] args)
  {
    CountDownLatch cdl = new CountDownLatch(10);
    for(int i = 0 ; i < 10 ; i++)
    {
        Thread2 wct = new Thread(new myRunnable(cd1));
        wct.start();
    }
     cd1.await();
  }
}