3个线程按顺序打印数字

我正在尝试编写一个简单的代码来按顺序打印数字。 场景就像

Thread Number T1 1 T2 2 T3 3 T1 4 T2 5 T3 6 T1 7 T2 8 T3 9 ...and so on. 

这里是

 public class ThreadNumberPrinter { Object monitor = new Object(); AtomicInteger number = new AtomicInteger(1); public static void main(String[] args) { ThreadNumberPrinter tnp = new ThreadNumberPrinter(); Thread t1 = new Thread(tnp.new Printer(1, 3)); Thread t2 = new Thread(tnp.new Printer(2, 3)); Thread t3 = new Thread(tnp.new Printer(3, 3)); t3.start(); t1.start(); t2.start(); } class Printer implements Runnable { int threadId; int numOfThreads; public Printer(int id, int nubOfThreads) { threadId = id; this.numOfThreads = nubOfThreads; } public void run() { print(); } private void print() { try { while (true) { Thread.sleep(1000l); synchronized (monitor) { if (number.get() % numOfThreads != threadId) { monitor.wait(); } else { System.out.println("ThreadId [" + threadId + "] printing -->" + number.getAndIncrement()); monitor.notifyAll(); } } } } catch (InterruptedException e) { e.printStackTrace(); } } } } 

但是在第二个线程运行并打印数字2之后,所有线程都进入等待阶段并且没有任何内容被打印出来。 我不确定我在哪里做错了。 任何帮助将不胜感激。

好吧,问题是modulo 3 % 30 。 将您的threadId更改为0..2而不是1..3并希望它应该工作。

下面的代码使用通知下一个线程打印数字,然后将其递增1然后再次通知下一个线程然后进入等待状态直到某个线程通知它的逻辑。 例如。 T1首先打印该值,然后使得布尔“秒”为真,以便T2打印下一个数字。 打印数字后T2使T3的布尔“第三”为真。 T3通过使布尔“第一”为真来为T1打印下一个数字做同样的事情。

T1 – > T2 – > T3 – > T1 – > T2 – > T3 – > ……..依此类推。

 public class Test{ public static volatile int i = 0; public static void main(String[] args) throws InterruptedException { Object monitor = new Object(); Notifier notifier = new Notifier(monitor); Thread thread1 = new Thread(notifier, "T1"); Thread thread2 = new Thread(notifier, "T2"); Thread thread3 = new Thread(notifier, "T3"); thread1.start(); thread2.start(); thread3.start(); } } class Notifier implements Runnable { private Object monitor = null; private static int i = 1; private static boolean first = true; private static boolean second = false; private static boolean third = false; public Notifier(Object objcurr) { this.monitor = objcurr; } @Override public void run() { try { while (true) { synchronized (monitor) { String Tname = Thread.currentThread().getName(); if (first && Tname.equalsIgnoreCase("T1")) { print(); first = false; second = true; monitor.notifyAll(); monitor.wait(); } else if (second && Tname.equalsIgnoreCase("T2")) { print(); second = false; third = true; monitor.notifyAll(); monitor.wait(); } else if (third && Tname.equalsIgnoreCase("T3")) { print(); third = false; first = true; monitor.notifyAll(); monitor.wait(); } else { monitor.wait(); } } Thread.sleep(1000); } } catch (Exception e) { e.printStackTrace(); } } private void print() { System.out.println(Thread.currentThread().getName() + " - " + Notifier.i++); } 
  public class TestClass { private volatile Integer count = 1; private volatile Integer threadIdToRun = 1; private Object object = new Object(); public static void main(String[] args) { TestClass testClass = new TestClass(); Thread t1 = new Thread(testClass.new Printer(1)); Thread t2 = new Thread(testClass.new Printer(2)); Thread t3 = new Thread(testClass.new Printer(3)); t1.start(); t2.start(); t3.start(); } class Printer implements Runnable { private int threadId; public Printer(int threadId) { super(); this.threadId = threadId; } @Override public void run() { try { while (count <= 20) { synchronized (object) { if (threadId != threadIdToRun) { object.wait(); } else { System.out.println("Thread " + threadId + " printed " + count); count += 1; if (threadId == 1) threadIdToRun = 2; else if (threadId == 2) threadIdToRun = 3; else if (threadId == 3) threadIdToRun = 1; object.notifyAll(); } } } } catch (Exception e) { e.printStackTrace(); } } } } 

以上程序给出输出

 Thread 1 printed 1 Thread 2 printed 2 Thread 3 printed 3 Thread 1 printed 4 Thread 2 printed 5 Thread 3 printed 6 Thread 1 printed 7 Thread 2 printed 8 Thread 3 printed 9 Thread 1 printed 10 Thread 2 printed 11 Thread 3 printed 12 Thread 1 printed 13 Thread 2 printed 14 Thread 3 printed 15 Thread 1 printed 16 Thread 2 printed 17 Thread 3 printed 18 Thread 1 printed 19 Thread 2 printed 20 

虽然这对于使用线程来说是一种糟糕的方式,但如果我们仍然想要它,那么通用的解决方案就是拥有一个工作线程来存储它的id:

 class Worker extends Thread { private final ResourceLock resourceLock; private final int threadNumber; private final AtomicInteger counter; private volatile boolean running = true; public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) { this.resourceLock = resourceLock; this.threadNumber = threadNumber; this.counter = counter; } @Override public void run() { while (running) { try { synchronized (resourceLock) { while (resourceLock.flag != threadNumber) { resourceLock.wait(); } System.out.println("Thread:" + threadNumber + " value: " + counter.incrementAndGet()); Thread.sleep(1000); resourceLock.flag = (threadNumber + 1) % resourceLock.threadsCount; resourceLock.notifyAll(); } } catch (Exception e) { System.out.println("Exception: " + e); } } } public void shutdown() { running = false; } } 

ResourceLock类将存储标志和最大线程数:

 class ResourceLock { public volatile int flag; public final int threadsCount; public ResourceLock(int threadsCount) { this.flag = 0; this.threadsCount = threadsCount; } } 

然后主类可以使用它如下:

 public static void main(String[] args) throws InterruptedException { final int threadsCount = 3; final ResourceLock lock = new ResourceLock(threadsCount); Worker[] threads = new Worker[threadsCount]; final AtomicInteger counter = new AtomicInteger(0); for(int i=0; i 

在经过一段时间的延迟之后,我们可能会停止计数,并且在worker中关闭方法会提供此规定。

  package com.sourav.mock.Thread; import java.util.concurrent.atomic.AtomicInteger; public class ThreeThreadComunication implements Runnable { AtomicInteger counter; int[] array; static final Object mutex = new Object(); public ThreeThreadComunication(int[] array, AtomicInteger counter){ this.counter = counter; this.array = array; } @Override public void run() { int i = 0; while(i < array.length){ synchronized(mutex){ if(Integer.parseInt(Thread.currentThread().getName()) == counter.get()){ System.out.println(array[i]); if(counter.get() == 3){ counter.getAndSet(1); }else{ int c = counter.get(); counter.getAndSet(++c); } i++; } mutex.notifyAll(); try { mutex.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } package com.sourav.mock.Thread; import java.util.concurrent.atomic.AtomicInteger; public class ThreeThreadComunicationTest { public static void main(String[] args) { AtomicInteger counter = new AtomicInteger(1); int[] array1 = new int[]{1, 4, 7}; int[] array2 = new int[]{2, 5, 8}; int[] array3 = new int[]{3, 6, 9}; ThreeThreadComunication obj1 = new ThreeThreadComunication(array1, counter); ThreeThreadComunication obj2 = new ThreeThreadComunication(array2, counter); ThreeThreadComunication obj3 = new ThreeThreadComunication(array3, counter); Thread t1 = new Thread(obj1, "1"); Thread t2 = new Thread(obj2, "2"); Thread t3 = new Thread(obj3, "3"); t1.start(); t2.start(); t3.start(); } } 
 public class EvenOdd1 { //public static String str ="str1"; public static void main(String[] args) { // TODO Auto-generated method stub EvenOdd1 edd1 = new EvenOdd1(); AbThread tr2 = new AbThread(0,edd1); AbThread tr3 = new AbThread(1,edd1); AbThread tr4 = new AbThread(2,edd1); tr2.start(); tr3.start(); tr4.start(); } } class AbThread extends Thread { int mod; int mod_count=1; EvenOdd1 edd1; public static int count=1; int num_thread=3; public AbThread(int mod,EvenOdd1 edd1){ this.mod = mod; this.edd1 = edd1; } public void run() { synchronized(edd1) { try{ while(true){ while(count%num_thread!=mod) edd1.wait(); if(count==30) break; print(); edd1.wait(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void print() { int val = mod==1?2*mod_count:(mod==2?3*mod_count:4*mod_count); System.out.println(Thread.currentThread().getName() + " : " + val); edd1.notifyAll(); count=count+1; this.mod_count++ ; } } 
 public class PrintThreadsSequentially { static int number = 1; static final int PRINT_NUMBERS_UPTO = 20; static Object lock = new Object(); static class SequentialThread extends Thread { int remainder = 0; int noOfThreads = 0; public SequentialThread(String name, int remainder, int noOfThreads) { super(name); this.remainder = remainder; this.noOfThreads = noOfThreads; } @Override public void run() { while (number < PRINT_NUMBERS_UPTO) { synchronized (lock) { while (number % noOfThreads != remainder) { // wait for numbers other than remainder try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(getName() + " value " + number); number++; lock.notifyAll(); } } } } public static void main(String[] args) { SequentialThread first = new SequentialThread("First Thread", 0, 4); SequentialThread second = new SequentialThread("Second Thread", 1, 4); SequentialThread third = new SequentialThread("Third Thread", 2, 4); SequentialThread fourth = new SequentialThread("Fourth Thread", 3, 4); first.start(); second.start(); third.start(); fourth.start(); } 

}

这个怎么样?

 public class PrintNumbers implements Runnable { public static final int NO_OF_THREADS = 3; public static final int MAX_DIGIT = 20; public static final String THREAD_NAME_PREFIX = "t"; volatile int current = 1; private Object lock = new Object(); public static void main(String[] args) { PrintNumbers printNumbers = new PrintNumbers(); for (int i = 1; i <= NO_OF_THREADS; i++) { new Thread(printNumbers, THREAD_NAME_PREFIX + i).start(); } } @Override public void run() { String printThread; while (current < MAX_DIGIT) { synchronized (lock) { if (current % NO_OF_THREADS != 0) { printThread = THREAD_NAME_PREFIX + current % NO_OF_THREADS; } else { printThread = THREAD_NAME_PREFIX + NO_OF_THREADS; } if (!printThread.equals(Thread.currentThread().getName())) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (printThread.equals(Thread.currentThread().getName())) { System.out.println(String.format("Thread %s : %s", Thread.currentThread().getName(), current)); current = current + 1; } lock.notifyAll(); } } } } 

ThreadSynchronization类可用于在’n’no之间打印数字。 线程的顺序。 逻辑是在每个连续线程之间创建一个公共对象,并使用’wait’,’notify’按顺序打印数字。 注意:最后一个线程将与第一个线程共享一个对象。

您可以在运行之前更改“maxThreads”值以增加或减少程序中的线程数。

 import java.util.ArrayList; import java.util.List; public class ThreadSynchronization { public static int i = 1; public static final int maxThreads = 10; public static void main(String[] args) { List list = new ArrayList<>(); for (int i = 0; i < maxThreads; i++) { list.add(new Object()); } Object currObject = list.get(maxThreads - 1); for (int i = 0; i < maxThreads; i++) { Object nextObject = list.get(i); RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false); Thread th = new Thread(a); th.setName("Thread - " + (i + 1)); th.start(); currObject = list.get(i); } } } class RunnableClass implements Runnable { private Object currObject; private Object nextObject; private boolean firstThread; public RunnableClass(Object currObject, Object nextObject, boolean first) { this.currObject = currObject; this.nextObject = nextObject; this.firstThread = first; } @Override public void run() { int i = 0; try { if (firstThread) { Thread.sleep(5000); firstThread = false; System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++); synchronized (nextObject) { nextObject.notify(); } } while (i++ < Integer.MAX_VALUE) { synchronized (currObject) { currObject.wait(); } System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++); Thread.sleep(1000); synchronized (nextObject) { nextObject.notify(); } } } catch (Exception e) { e.printStackTrace(); } } } 

我尝试过以下简单的方法,使用三个线程按顺序打印,它运行良好。

 public class AppPrint123 { static int count = 1; static int counter = 1; static Object lock = new Object(); public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { while (true) { synchronized (lock) { try { Thread.sleep(100); while (count != 1) { lock.wait(); } System.out.println(Thread.currentThread().getName() + ": " + counter); count++; counter++; } catch (InterruptedException e) { e.printStackTrace(); } lock.notifyAll(); } } } }, "T1"); Thread t2 = new Thread(new Runnable() { public void run() { while (true) { synchronized (lock) { try { Thread.sleep(100); while (count != 2) { lock.wait(); } System.out.println(Thread.currentThread().getName() + ": " + counter); counter++; } catch (InterruptedException e) { e.printStackTrace(); } lock.notifyAll(); } } } }, "T2"); Thread t3 = new Thread(new Runnable() { public void run() { while (true) { synchronized (lock) { try { Thread.sleep(100); while (count != 3) { lock.wait(); } System.out.println(Thread.currentThread().getName() + ": " + counter); count = count - 2; counter++; } catch (InterruptedException e) { e.printStackTrace(); } lock.notifyAll(); } } } }, "T3"); t1.start(); t2.start(); t3.start(); } } 

如果要使用三个线程按顺序生成类似123123123的输出,则可以打印计数变量。

 public class ThreadTask implements Runnable { private int counter; private int threadID; private final Object lock; private int prev; public ThreadTask(Object obj, int threadid, int counter){ this.lock = obj; // monitor this.threadID = threadid; //id of thread this.counter = counter; this.prev =threadid + 1; } public void run(){ while(counter<100){ synchronized(lock){ if(counter == this.prev && this.threadID % 3 == this.threadID){ System.out.println("T" + this.threadID + " = " + this.prev); this.prev = this.prev + 3; } counter++; lock.notifyAll(); try{ lock.wait(); }catch(Exception e){ e.printStackTrace(); } } } } } public class ThreadMain { static volatile int counter = 1; public static void main(String args[]) throws InterruptedException{ final Object lock = new Object(); ThreadTask first = new ThreadTask(lock, 0, counter); ThreadTask second = new ThreadTask(lock, 1, counter); ThreadTask third = new ThreadTask(lock, 2, counter); Thread t1 = new Thread(first, "first"); Thread t2 = new Thread(second, "second"); Thread t3 = new Thread(third, "third"); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); } } 
 package ThreadCoreConcepts; import java.util.ArrayList; import java.util.List; /** * 3 Thread T1,T2,T3 will print output {1,2,3 4,5,6 7,8,9} Where T1 will print * {1,4,7} , T2 will print { 2,5,8} and T3 will print {3,6,9} * * @author harsmahe * */ public class ThreeThreadSequenceGen { private volatile static int value = 1; public static void main(String args[]) throws InterruptedException { ThreeThreadSequenceGen gen = new ThreeThreadSequenceGen(); Object mutex = new Object(); Thread t1 = new Thread(gen.new RunThread(1, mutex)); t1.setName("1"); Thread t2 = new Thread(gen.new RunThread(2, mutex)); t2.setName("2"); Thread t3 = new Thread(gen.new RunThread(3, mutex)); t3.setName("3"); t1.start(); t2.start(); t3.start(); } class RunThread implements Runnable { private int start = 0; private Object mutex; private List list = new ArrayList(); public RunThread(final int start, Object mutex) { // TODO Auto-generated constructor stub this.start = start; this.mutex = mutex; } @Override public void run() { try { while (value <= 9) { // while (true) { // TODO Auto-generated method stub int name = Integer.valueOf(Thread.currentThread().getName()); // System.out.println("[" + Thread.currentThread().getName() // + "]"); // notifyAll(); synchronized (mutex) { if (name == 1 && value == start) { list.add(value); System.out.println("[" + Thread.currentThread().getName() + "]" + value); start = start + 3; value++; mutex.notifyAll(); mutex.wait(); } else if (name == 2 && value == start) { System.out.println("[" + Thread.currentThread().getName() + "]" + value); list.add(value); start = start + 3; value++; mutex.notifyAll(); mutex.wait(); } else if (name == 3 && value == start) { System.out.println("[" + Thread.currentThread().getName() + "]" + value); list.add(value); start = start + 3; value++; mutex.notifyAll(); if (value < 9) { mutex.wait(); } } else { mutex.notifyAll(); // mutex.wait(); } } } } catch (Exception e) { e.printStackTrace(); } finally { // System.out.println(list); } } } } enter code here