使用Java中的三个线程依次打印数字

时间:2020-01-09 10:35:35  来源:igfitidea点击:

这篇文章显示了如何使用Java编写程序以使用三个线程按顺序打印数字。如果有三个线程T1,T2,T3,则这些线程应按以下方式交替打印数字:

T11
T22
T33
T14
T25
T36
..
..
..

使用3个线程打印数字-Java程序

在程序中,为每个线程分配一个数字(分别为0、1和2)。在线程打印数字之前,将每个数字除以3,并且所分配的数字等于该除法其余部分的线程才有资格打印该数字。

例如

如果数字%3 == 0,则T1打印数字
如果数字%3 == 1,则T2打印数字
如果数字%3 == 2,则T3打印数字

该程序用于使用线程顺序打印数字,可以仅使用synced关键字编写,也可以使用wait,notify和notifyAll方法进行编写,以进行线程间通信。

使用3个线程和synced关键字打印数字

public class PrintNumbers {
  final static int MAX_NUMBERS = 10;
  public static void main(String[] args) {
    // shared object
    PrintNumbers obj = new PrintNumbers();
    // Creating 3 threads
    Thread t1 = new Thread(new NumberRunnable(obj, 0), "T1");
    Thread t2 = new Thread(new NumberRunnable(obj, 1), "T2");
    Thread t3 = new Thread(new NumberRunnable(obj, 2), "T3");
    t1.start();
    t2.start();
    t3.start();
  }
}

class NumberRunnable implements Runnable{
  PrintNumbers obj;
  int threadNumber;
  static int number = 0;
  NumberRunnable(PrintNumbers obj, int result){
    this.obj = obj;
    this.threadNumber = result;
  }
  @Override
  public void run() {
    while (number < PrintNumbers.MAX_NUMBERS) {
      synchronized(obj) {	
        // check again for (number < PrintNumbers.MAX_NUMBERS) otherwise one more number my be
        // printed by another thread
        if(number % 3 == threadNumber && number < PrintNumbers.MAX_NUMBERS){
          System.out.println(Thread.currentThread().getName() + " - " + ++number);
        }
      }
    }                             
  }
}

输出:

T1 - 1
T2 - 2
T3 - 3
T1 - 4
T2 - 5
T3 - 6
T1 - 7
T2 - 8
T3 - 9
T1 - 10

使用3个线程打印数字并等待通知

使用线程打印数字并等待通知的Java程序与上面的示例非常相似,不同之处在于现在有一个等待条件(while(number%3!= threadNumber))。除非分配的线程号不等于该数字除以3的余数,否则将使线程等待。

仅当分配的线程号等于除数线程的其余部分时,才会打印该数字并通知其他等待线程,以便其中一个可以进入同步块。

代码中的另一件有趣的事情是这种情况(数字<PrintNumbers.MAX_NUMBERS – 2)。为什么要检查少于所需数量的两个?这是因为无论如何,这三个线程都将运行循环,而对于值8本身,一个线程会将其递增到9,另一个将递增到10.

public class PrintNumbers {
  final static int MAX_NUMBERS = 10;
  public static void main(String[] args) {
    // shared object
    PrintNumbers obj = new PrintNumbers();
    // Creating 3 threads
    Thread t1 = new Thread(new NumberRunnable(obj, 0), "T1");
    Thread t2 = new Thread(new NumberRunnable(obj, 1), "T2");
    Thread t3 = new Thread(new NumberRunnable(obj, 2), "T3");
    t1.start();
    t2.start();
    t3.start();
  }
}

class NumberRunnable implements Runnable{
  PrintNumbers obj;
  int threadNumber;
	static volatile int number = 0;
  NumberRunnable(PrintNumbers obj, int result){
    this.obj = obj;
    this.threadNumber = result;
  }
  @Override
  public void run() {   
    synchronized(obj) {	
      while (number < PrintNumbers.MAX_NUMBERS - 2) {
        while(number % 3 != threadNumber){
          try {
            obj.wait();
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
        System.out.println(Thread.currentThread().getName() + " - " + ++number);
        obj.notifyAll();
      }
    }                            
  }
}

输出:

T1 - 1
T2 - 2
T3 - 3
T1 - 4
T2 - 5
T3 - 6
T1 - 7
T2 - 8
T3 - 9
T1 - 10