2013-04-14 61 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”,相当具有误导性。 –