2013-04-14 110 views
1

給定三個線程(1-3),它​​們打印一封字母A-C,如何保證輸出順序?如何確保Java線程按特定順序運行

我想線程的輸出爲「ABCABCABC」

+0

你是否被迫使用線程,或者你只是在一個線程中做的東西? –

+0

這是一個學校任務嗎?查看如何在Java中進行同步。 – boxed

回答

3

線程獨立運行,所以你永遠不會得到這樣的輸出,除非你進行特別的努力來同步線程。預計3個獨立運行的線程將打印「隨機」輸出,因爲它要由OS來調度線程。

-2

ExecutorService

,提供方法來管理終端和方法 能夠產生未來爲跟蹤一個或多個 異步任務執行遺囑執行人。

ExecutorService可以關閉,這會導致它拒絕新的 任務。提供了兩種不同的方法來關閉執行程序服務 。 shutdown()方法將允許先前提交的 任務在終止之前執行,而shutdownNow()方法 阻止等待任務啓動並嘗試停止當前執行任務的 。在終止時,執行者沒有任務主動執行,沒有任務等待執行,並且沒有任何新任務可以被提交。 。應關閉一個未使用的ExecutorService以允許回收其資源 。

方法提交通過創建並返回一個可用於取消 執行和/或等待完成的Future延伸鹼方法Executor.execute(了java.lang.Runnable) 。方法invokeAny和invokeAll 執行最常用的批量執行形式,執行一個 任務集合,然後完成至少一個或全部等於 的完成。 (類ExecutorCompletionService可用於編寫 這些方法的自定義變體。)

Executors類爲此包中提供的執行程序服務 提供工廠方法。

+0

這與這個問題有什麼關係? – boxed

-1
public class ThreadOrderTest { 

int status = 1; 

public static void main(String[] args) { 
    ThreadOrderTest threadOrderTest = new ThreadOrderTest(); 
    A a = new A(threadOrderTest); 
    B b = new B(threadOrderTest); 
    C c = new C(threadOrderTest); 
    a.start(); 
    b.start(); 
    c.start(); 
} 
} 

class A extends Thread { 

ThreadOrderTest threadOrderTest; 

A(ThreadOrderTest threadOrderTest) { 
    this.threadOrderTest = threadOrderTest; 
} 

@Override 
public void run() { 
    try { 
     synchronized (threadOrderTest) { 
      for (int i = 0; i < 10; i++) { 
       while (threadOrderTest.status != 1) { 
        threadOrderTest.wait(); 
       } 
       System.out.print("A "); 
       threadOrderTest.status = 2; 
       threadOrderTest.notifyAll(); 
      } 
     } 
    } catch (Exception e) { 
     System.out.println("Exception 1 :" + e.getMessage()); 
    } 
} 
} 

class B extends Thread { 

ThreadOrderTest threadOrderTest; 

B(ThreadOrderTest threadOrderTest) { 
    this.threadOrderTest = threadOrderTest; 
} 

@Override 
public void run() { 
    try { 
     synchronized (threadOrderTest) { 
      for (int i = 0; i < 10; i++) { 
       while (threadOrderTest.status != 2) { 
        threadOrderTest.wait(); 
       } 
       System.out.print("B "); 
       threadOrderTest.status = 3; 
       threadOrderTest.notifyAll(); 
      } 
     } 
    } catch (Exception e) { 
     System.out.println("Exception 2 :" + e.getMessage()); 
    } 
} 
} 

class C extends Thread { 

ThreadOrderTest threadOrderTest; 

C(ThreadOrderTest threadOrderTest) { 
    this.threadOrderTest = threadOrderTest; 
} 

@Override 
public void run() { 
    try { 
     synchronized (threadOrderTest) { 
      for (int i = 0; i < 10; i++) { 
       while (threadOrderTest.status != 3) { 
        threadOrderTest.wait(); 
       } 
       System.out.println("C "); 
       threadOrderTest.status = 1; 
       threadOrderTest.notifyAll(); 
      } 
     } 
    } catch (Exception e) { 
     System.out.println("Exception 3 :" + e.getMessage()); 
    } 
} 
} 
0

您可以通過合併CountDownLatchCyclicBarrier實現這一目標。下面是示例代碼:

package org.orange.didxga; 

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.CyclicBarrier; 

public class ThreadExecutionOrder { 

    private CountDownLatch countDownLatch = new CountDownLatch(2); 
    private CountDownLatch countDownLatch1 = new CountDownLatch(1); 
    private CyclicBarrier barrier; 
    private final Object monitor = new Object(); 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     new ThreadExecutionOrder().test(); 
    } 

    public void test() { 
     Runnable t1 = new Runnable() { 

      @Override 
      public void run() { 
       System.out.print("A"); 
       countDownLatch1.countDown(); 
       countDownLatch.countDown(); 
       try { 
        barrier.await(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } catch (BrokenBarrierException e) { 
        e.printStackTrace(); 
       } 
      } 

     }; 
     Runnable t2 = new Runnable() { 

      @Override 
      public void run() { 
       try { 
        countDownLatch1.await(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.print("B"); 
       countDownLatch.countDown(); 
       try { 
        barrier.await(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } catch (BrokenBarrierException e) { 
        e.printStackTrace(); 
       } 
      } 

     }; 
     Runnable t3 = new Runnable() { 

      @Override 
      public void run() { 
       try { 
        countDownLatch.await(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.print("C"); 
       try { 
        barrier.await(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } catch (BrokenBarrierException e) { 
        e.printStackTrace(); 
       } 
      } 

     }; 
     for(int i=0; i<3; i++) { 
      barrier = new CyclicBarrier(3, new Runnable() { 
       @Override 
       public void run() { 
        synchronized (monitor) { 
         countDownLatch = new CountDownLatch(2); 
         countDownLatch1 = new CountDownLatch(1); 
         monitor.notify(); 
        } 
       } 

      }); 
      new Thread(t1).start(); 
      new Thread(t2).start(); 
      new Thread(t3).start(); 
      synchronized (monitor) { 
       try { 
        monitor.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

} 
2

這可能不是什麼的線程應該做的,但是,它可以通過簡單地使用連接(其要求開始ING線程等待開始的完成來實現ED線程。

class A implements Runnable { 

@Override 
public void run() { 
    try { 
     Thread.sleep(12); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("ClassA : A"); 
} 

} 

class B implements Runnable { 

@Override 
public void run() { 
    try { 
     Thread.sleep(12); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("ClassB : B"); 
} 

} 

class C implements Runnable { 

@Override 
public void run() { 
    try { 
     Thread.sleep(12); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("ClassC : C"); 
} 

} 

public class OrderedThreadApp { 
public static void main(String[] args) { 

    Thread a = new Thread(new A()); 
    Thread b = new Thread(new B()); 
    Thread c = new Thread(new C()); 

    a.start(); 
    try { 
     a.join(); 
     b.start(); 
     b.join(); 
     c.start(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
} 
0

您可以使用等待並通知間通信。在這裏,我反過來用int變量的線程之間的信令。

public class ThreadInterleaving{ 
    public static void main(String[] args){ 

    MyThread h = new MyThread(); 

    Thread t1 = new Thread(h); 
    Thread t2 = new Thread(h); 
    Thread t3 = new Thread(h); 

    t1.start(); 
    t2.start(); 
    t3.start(); 

    } 
} 

class MyThread implements Runnable{ 
    public static int turn; 

    @Override 
    public void run(){ 
     for(int i =0;i<3;i++){ 
      synchronized(this){ 
       if(turn == 0){ 
        System.out.println("Thread1"); 
        turn =1 ; 
        notify(); 
       }else{ 
        try{ 
         wait(); 
        }catch(InterruptedException ie){ 

        } 
       } 

       if(turn == 1){ 
        System.out.println("Thread2"); 
        turn = 2; 
        notify(); 
       }else{ 
        try{ 
         wait(); 
        }catch(InterruptedException ie){ 

        } 
       } 

       if(turn == 2){ 
        System.out.println("Thread3"); 
        System.out.println("*********"); 
        turn = 0; 
        notify(); 
       }else{ 
        try{ 
         wait(); 
        }catch(InterruptedException ie){   

        } 
       } 
      } 
     } 
    } 
} 

/*Output 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
Thread1 
Thread2 
Thread3 
********* 
*/ 
+2

這對我來說看起來很奇怪。當然,每個線程都應該知道它擁有哪個「轉向」,並等待轉向 - 目前*任何*線程都可以打印出「線程1」,*任何*線程都可以打印出「線程2」和*任何*線程可以打印出「Thread3」,相當具有誤導性。 –