按顺序java运行3个线程

我有3个线程第1次打印第2次打印B第3次打印C.

我想按顺序打印ABCABCABC等等……

所以我在下面编写了这个程序,但我无法实现同样的目标。 我知道当status = 1时,例如B1和C1线程正在等待,当我执行notifyAll()时,两个等待线程都被唤醒,并且根据CPU分配,它可能会打印B或C.

在这种情况下,我只想在A之后打印B.

我需要做什么修改。

public class NotifyAllExample { int status=1; public static void main(String[] args) { NotifyAllExample notifyAllExample = new NotifyAllExample(); A1 a=new A1(notifyAllExample); B1 b=new B1(notifyAllExample); C1 c=new C1(notifyAllExample); a.start(); b.start(); c.start(); } } class A1 extends Thread{ NotifyAllExample notifyAllExample; A1(NotifyAllExample notifyAllExample){ this.notifyAllExample = notifyAllExample; } @Override public void run() { try{ synchronized (notifyAllExample) { for (int i = 0; i < 100; i++) { if(notifyAllExample.status!=1){ notifyAllExample.wait(); } System.out.print("A "); notifyAllExample.status = 2; notifyAllExample.notifyAll(); } } }catch (Exception e) { System.out.println("Exception 1 :"+e.getMessage()); } } } class B1 extends Thread{ NotifyAllExample notifyAllExample; B1(NotifyAllExample notifyAllExample){ this.notifyAllExample = notifyAllExample; } @Override public void run() { try{ synchronized (notifyAllExample) { for (int i = 0; i < 100; i++) { if(notifyAllExample.status!=2){ notifyAllExample.wait(); } System.out.print("B "); notifyAllExample.status = 3; notifyAllExample.notifyAll(); } } }catch (Exception e) { System.out.println("Exception 2 :"+e.getMessage()); } } } class C1 extends Thread{ NotifyAllExample notifyAllExample; C1(NotifyAllExample notifyAllExample){ this.notifyAllExample = notifyAllExample; } @Override public void run() { try{ synchronized (notifyAllExample) { for (int i = 0; i < 100; i++) { if(notifyAllExample.status!=3){ notifyAllExample.wait(); } System.out.print("C "); notifyAllExample.status = 1; notifyAllExample.notifyAll(); } } }catch (Exception e) { System.out.println("Exception 3 :"+e.getMessage()); } } } 

将这些IF语句转换为WHILE语句以获得所需的行为:

 if (notifyAllExample.status != 2){ notifyAllExample.wait(); } 

 while (notifyAllExample.status != 2){ notifyAllExample.wait(); } 

这将确保如果通知一个线程,它将不会退出while循环,直到状态值达到预期值。

此外,将status标记为volatile,以便线程不具有本地副本。

  public class RunThreadsInOrder implements Runnable { static int numThread = 1; static int threadAllowedToRun = 1; int myThreadID; private static Object myLock = new Object(); public RunThreadsInOrder() { this.myThreadID = numThread++; System.out.println("Thread ID:" + myThreadID); } @Override public void run() { synchronized (myLock) { while (myThreadID != threadAllowedToRun) { try { myLock.wait(); } catch (InterruptedException e) { } catch (Exception e) {} } try { Thread.sleep(2000); } catch (InterruptedException e) { } System.out.println("myThreadID is running: " + myThreadID); myLock.notifyAll(); threadAllowedToRun++; } } public static void main(String[] args) { // TODO Auto-generated method stub Thread t1 = new Thread(new RunThreadsInOrder()); Thread t2 = new Thread(new RunThreadsInOrder()); Thread t3 = new Thread(new RunThreadsInOrder()); Thread t4 = new Thread(new RunThreadsInOrder()); Thread t5 = new Thread(new RunThreadsInOrder()); Thread t6 = new Thread(new RunThreadsInOrder()); Thread t7 = new Thread(new RunThreadsInOrder()); t7.start(); t6.start(); t5.start(); t4.start(); t3.start(); t2.start(); t1.start(); } } 

你需要更换

 if (notifyAllExample.status!=1) 

 while (notifyAllExample.status!=1) 

和其他2个class级一样。 如果没有,那么一旦等待退出线程继续而不知道它是否轮到它。

更换:

 if(notifyAllExample.status!=1){ notifyAllExample.wait(); } 

有:

 while(notifyAllExample.status!=1){ notifyAllExample.wait(); } 

因此在所有类别中。

  public class Main { public static void main(String[] args) throws IOException{ Thread t1 = new Thread(new A(), "1"); Thread t2 = new Thread(new A(), "2"); Thread t3 = new Thread(new A(), "3"); t1.start(); try{ t1.join(); }catch (Exception e){ } t2.start(); try{ t2.join(); }catch (Exception e){ } t3.start(); try{ t3.join(); }catch (Exception e){ } } } class A implements Runnable{ public void run(){ System.out.println(Thread.currentThread().getName()); } } 

或者您可以使用Executor Framework

 public class Sequence { int valve = 1; public static void main(String[] args){ Sequence s = new Sequence(); ExecutorService es = Executors.newFixedThreadPool(3); List rList = new ArrayList<>(); rList.add(new A(s)); rList.add(new B(s)); rList.add(new C(s)); for(int i = 0; i < rList.size(); i++){ es.submit(rList.get(i)); } es.shutdown(); } } class A implements Runnable{ Sequence s; A(Sequence s){ this.s = s; } public void run(){ synchronized (s) { for (int i = 0; i < 10; i++) { while (s.valve != 1) { try { s.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("A"); s.valve = 2; s.notifyAll(); } } } } class B implements Runnable{ Sequence s; B(Sequence s){ this.s = s; } public void run() { synchronized (s) { for (int i = 0; i < 10; i++) { while (s.valve != 2) { try { s.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("B"); s.valve = 3; s.notifyAll(); } } } } class C implements Runnable{ Sequence s; C(Sequence s){ this.s = s; } public void run() { synchronized (s) { for(int i = 0; i < 10; i++) { while (s.valve != 3) { try { s.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("C"); s.valve = 1; s.notifyAll(); } } } } 

在第一种情况下,每个线程的连接使线程彼此等待。 在第二种情况下,列表存储线程,执行器一个接一个地执行它们,创建3个线程

另一种方法是只存在一个可运行的类,并且线程之间的通信是通过主类中的静态变量和runnable类中的变量完成的。

 import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Seq { int i = 1; public static void main(String[] args){ Seq s = new Seq(); Common c1 = new Common(s, 1); Common c2 = new Common(s, 2); Common c3 = new Common(s, 3); List l = new ArrayList<>(); l.add(c1); l.add(c2); l.add(c3); ExecutorService es = Executors.newFixedThreadPool(3); for(int i = 0; i < 3; i++){ es.submit(l.get(i)); } es.shutdown(); } } class Common implements Runnable{ Seq s; int o; Common(Seq s, int o){ this.s = s; this.o = o; } public void run(){ synchronized (s) { for (int z = 0; z < 100; z++) { if(si > 3) si = 1; while (si != o) { try { s.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(o); s.i++; s.notifyAll(); } } } } 

我被要求在一次采访中编写一个类似的程序,其附加条件是它应该是可扩展的,我们可以提供自己的线程数,并且他们应该打印字符,第一个线程打印’A’然后是后续线程印刷B,C,D等。 这是我如何做到的。

 public class AlternateCharPrinter { public static char ch = 65; private static void createAndStartThreads(int count) { Object lock = new Object(); for (int i = 0; i < count; i++) { new Thread(new AlternateCharRunner((char) (65 + i), lock)).start(); } } public static void main(String[] args) { createAndStartThreads(4); } } class AlternateCharRunner implements Runnable { private char ch; private Object lock; private static int runnerCount; public AlternateCharRunner(char ch, Object lock) { this.ch = ch; this.lock = lock; runnerCount++; } @Override public void run() { while (true) { synchronized (lock) { while (ch != AlternateCharPrinter.ch) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(AlternateCharPrinter.ch++); if (AlternateCharPrinter.ch == (65 + runnerCount)) { AlternateCharPrinter.ch = 65; } lock.notifyAll(); } } } } 

解决这个问题的最简单的解决方案可以是:

 public class PrintInOrder implements Runnable { private int valueToPrint; private int id; private static int turn = 1; private static int RESET_TURN_THRESHOLD = 3; public PrintInOrder() { this.valueToPrint = -1; } public PrintInOrder(int id, int val) { this.id = id; this.valueToPrint = val; } @Override public void run() { while(true) { if (turn == this.id) { System.out.println(Thread.currentThread().getName() + "::::" + valueToPrint); turn++; } if (turn > RESET_TURN_THRESHOLD) { turn = 1; } } } public static void main(String []args) { Thread t1 = new Thread(new PrintInOrder(1, 1)); t1.setName("THREAD-1"); t1.start(); Thread t2 = new Thread(new PrintInOrder(2, 2)); t2.setName("THREAD-2"); t2.start(); Thread t3 = new Thread(new PrintInOrder(3, 3)); t3.setName("THREAD-3"); t3.start(); } 

}

 /* OUTPUT:::: THREAD-1::::1 THREAD-2::::2 THREAD-3::::3 THREAD-1::::1 THREAD-2::::2 THREAD-3::::3 THREAD-1::::1 THREAD-2::::2 THREAD-3::::3 THREAD-1::::1 THREAD-2::::2 THREAD-3::::3 THREAD-1::::1 THREAD-2::::2 THREAD-3::::3 THREAD-1::::1 THREAD-2::::2 THREAD-3::::3 ... */ 

我认为使用join实现这一点更简单。 例:

  public static void main(String[] args) { final Thread t1 = new Thread("t1") { @Override public void run() { System.out.println("i am thread: " + Thread.currentThread().getName()); } }; final Thread t2 = new Thread(t1, "t2") { @Override public void run() { t1.start(); try { t1.join(); } catch ( InterruptedException e ) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("i am thread: " + Thread.currentThread().getName()); } }; Thread t3 = new Thread(t2, "t3") { @Override public void run() { t2.start(); try { t2.join(); } catch ( InterruptedException e ) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("i am thread: " + Thread.currentThread().getName()); } }; t3.start(); 

}

这是我的解决方案,请尝试告诉我

 package thread; class SyncPrinter { public static void main(String[] args) { SyncPrinterAction printAction1 = new SyncPrinterAction(new int[]{1,5,9,13}, true); SyncPrinterAction printAction2 = new SyncPrinterAction(new int[]{2,6,10,14}, true); SyncPrinterAction printAction3 = new SyncPrinterAction(new int[]{3,7,11,15}, true); SyncPrinterAction printAction4 = new SyncPrinterAction(new int[]{4,8,12,16}, false); printAction1.setDependentAction(printAction4); printAction2.setDependentAction(printAction1); printAction3.setDependentAction(printAction2); printAction4.setDependentAction(printAction3); new Thread(printAction1, "T1").start();; new Thread(printAction2, "T2").start(); new Thread(printAction3, "T3").start(); new Thread(printAction4, "T4").start(); } } class SyncPrinterAction implements Runnable { private volatile boolean dependent; private SyncPrinterAction dependentAction; int[] data; public void setDependentAction(SyncPrinterAction dependentAction){ this.dependentAction = dependentAction; } public SyncPrinterAction( int[] data, boolean dependent) { this.data = data; this.dependent = dependent; } public SyncPrinterAction( int[] data, SyncPrinterAction dependentAction, boolean dependent) { this.dependentAction = dependentAction; this.data = data; this.dependent = dependent; } @Override public void run() { synchronized (this) { for (int value : data) { try { while(dependentAction.isDependent()) //System.out.println("\t\t"+Thread.currentThread().getName() + " :: Waithing for dependent action to complete"); wait(100); } catch (InterruptedException e) { e.printStackTrace(); } dependentAction.setDependent(true); System.out.println(Thread.currentThread().getName() + " :: " +value); dependent = false; } } } private void setDependent(boolean dependent) { this.dependent = dependent; } private boolean isDependent() { return dependent; } }