跟踪执行线程

时间:2014-04-19 02:19:08

标签: java multithreading concurrency

我试图弄清楚如何跟踪我的应用程序产生的所有线程。最初,我以为我已经想到了使用CyclicBarrier,但是我看到线程在我的等待调用之后执行。

以下是工作伪代码:

public class ThreadTesterRunner {

    public static void main(String[] args) throws InterruptedException {

        final CyclicBarrier cb = new CyclicBarrier(1);
        ThreadRunner tr = new ThreadRunner(cb);
        Thread t = new Thread(tr, "Thread Runner");
        t.start();

        boolean process = true;
        // wait until all threads process, then print reports
        while (process){
            if(tr.getIsFinished()){
                System.out.println("Print metrics");
                process = false;
            }
            Thread.sleep(1000);
        }
    }
}


class ThreadRunner implements Runnable {
    static int timeOutTime = 2;
    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    private final CyclicBarrier barrier;
    private boolean isFinished=false;

    public ThreadRunner(CyclicBarrier cb) {
        this.barrier = cb;
    }

    public void run(){
        try {
            boolean stillLoop = true; int i = 0;
            while (stillLoop){
                int size;
                Future<Integer> future = null;
                try {
                    future = executorService.submit(new Reader()); // sleeps
                    size = future.get();
                } catch (InterruptedException | ExecutionException ex) {
                    // handle Errs
                }

                if(i == 3){
                    stillLoop = false;
                    this.barrier.await();
                    this.isFinished=true;
                }
                //System.out.println("i = "+i+"  Size is: "+size+"\r");
                i++;
            }
        } catch (InterruptedException | BrokenBarrierException e1) {
            e1.printStackTrace();
        }
    }

    public boolean getIsFinished(){
        return this.isFinished;
    }
}

class Reader implements Callable {
    private ExecutorService executorService = Executors.newFixedThreadPool(1);

    @Override
    public Object call() throws Exception {
        System.out.println("Reading...");
        Thread.sleep(2000);
        executorService.submit(new Writer());
        return 1000;
    }
}

class Writer implements Callable {
    @Override
    public Void call() throws Exception {
        Thread.sleep(4000);
        System.out.println("Wrote");    
        return null;
    }
}

有人建议在所有线程运行后只打印“打印指标”吗?

2 个答案:

答案 0 :(得分:1)

您似乎无法与ReaderWriter线程进行协调,这些线程是您要等待的线程。如果您将同步障碍传递给这些线程,以便它们可以在完成后进行注册和发出信号,那么它可以正常工作。

这是使用Phaser代替CyclicBarrier重写的版本。请注意,每个ReaderWriter在构造时会自行注册,并在执行完成后通知同步障碍:

public class ThreadTesterRunner {
    public static void main(String[] args) throws InterruptedException {
        final Phaser cb = new Phaser();
        ThreadRunner tr = new ThreadRunner(cb);
        Thread t = new Thread(tr, "Thread Runner");
        t.start();

        boolean process = true;
        // wait until all threads process, then print reports
        while (process){
            if(tr.getIsFinished()){
                System.out.println("Print metrics");
                process = false;
            }
            //else {
            //  System.out.println("Waiting:  registered=" + cb.getRegisteredParties() + ", arrived=" + cb.getArrivedParties() + ", unarrived=" + cb.getUnarrivedParties());
            //}
            Thread.sleep(1000);
        }
    }
}


class ThreadRunner implements Runnable {
    static int timeOutTime = 2;
    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    private final Phaser barrier;
    private boolean isFinished=false;

    public ThreadRunner(Phaser phaser) {
        this.barrier = phaser;
    }

    public void run(){
        try {
            boolean stillLoop = true; int i = 0;
            while (stillLoop){
                int size;
                Future<Integer> future = null;
                try {
                    future = executorService.submit(new Reader(this.barrier)); // sleeps
                    size = future.get();
                } catch (InterruptedException | ExecutionException ex) {
                    // handle Errs
                }

                if(i == 3){
                    stillLoop = false;
                    this.barrier.awaitAdvance(0);
                    this.isFinished=true;
                }
                //System.out.println("i = "+i+"  Size is: "+size+"\r");
                i++;
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    public boolean getIsFinished(){
        return this.isFinished;
    }
}

class Reader implements Callable {
    private Phaser barrier;
    private ExecutorService executorService = Executors.newFixedThreadPool(1);

    public Reader(Phaser phase) {
        phase.register();
        this.barrier = phase;
    }

    @Override
    public Object call() throws Exception {
        System.out.println("Reading...");
        Thread.sleep(2000);
        executorService.submit(new Writer(this.barrier));
        this.barrier.arrive();
        return 1000;
    }
}

class Writer implements Callable {
    private Phaser barrier;

    public Writer(Phaser phase) {
        phase.register();
        this.barrier = phase;
    }

    @Override
    public Void call() throws Exception {
        Thread.sleep(4000);
        System.out.println("Wrote");
        this.barrier.arrive();
        return null;
    }
}

答案 1 :(得分:0)

从我所看到的你不是在等Writer完成Reader。那是你看到的问题吗?

您还在不同步的情况下从多个线程访问isFinished(但是,这可能会在这种情况下延迟循环终止)。

我没有看到CyclicBarrier做任何事情。

不确定你要做什么,但我想我能做到多么简单。例如,Reader and Writer可以组合成一个任务吗?然后,等待他们完成只会是:

executorService.invokeAll(tasks);
System.out.println("Print metrics");

其中tasks是一组任务(另请参阅this javadoc