2014-04-19 178 views
3

我想弄清楚如何跟蹤我的應用程序產生的所有線程。最初,我想我已經想出了使用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; 
    } 
} 

任何人都可以提出一個方法,只打印「打印指標」的所有線程都運行後?

回答

1

它似乎並不像你做什麼你Reader協調和Writer線程,這些是你想要等待的線程。如果您將同步屏障傳遞給這些線程,以便它們在完成時可以註冊併發出信號,則它可以正常工作。

這裏是一個版本改寫,使用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; 
    } 
} 
+0

完美工作。謝謝你的建議! – Dan

+0

剛剛發現了「Phaser」對象。再次感謝。 – Dan

0

從我所看到的你不會等待Writer完成在Reader。這是你看到的問題嗎?

您也正在訪問isFinished從多個線程沒有同步(但是,這可能會延遲在這種情況下循環終止)。

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

不知道你在做什麼,但我想想我能做到多簡單。例如,Reader和Writer可以合併爲一個任務嗎?然後,等待他們完成只會是:

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

其中tasks是任務的集合(也見this javadoc

+0

感謝您的評論和建議。 Unfort。作家必須從讀者身上產生,讀者不能阻止和等待它。作家和讀者需要在某些情況下並行運行。 當寫入器被移除時,CyclicBarrier不起作用。然而,作家是必要的條件。 (爲了測試CB代碼,你可以註釋掉處理Writer的executorservice並且看它是否有效。'Future f = executorService.submit(new Writer());') – Dan