多线程顺序打印100个数
多线程顺序打印100个数
一、前言
昨天群友问了个有意思的问题
多线程打印1-100,线程1打印123,线程2打印456,线程3答应789,以此类推 不能出现乱序
故今天实现一番
二、实现
本人的思路是为每个线程编号, 定义公共变量nextPrintThreadSeq表示将要打印的线程编号, 以此来保证有序
/** * 多线程打印1-100,线程1打印123,线程2打印456,线程3答应789,以此类推 不能出现乱序 * @author TimFruit * @date 20-4-25 上午8:41 */ public class LockPrintOneHundred { //通过序号来保证线程顺序 //下一个将要打印的线程序号 private static volatile int nextPrintThreadSeq=0; //每个线程起始打印的数字 private static volatile int eachStartNumber=1; private static Lock lock=new ReentrantLock(); public static void main(String[] args) { int nThread=3; List<Thread> threads=new ArrayList<>(); Thread thread; for(int i=0;i<nThread;i++){ thread=new Thread(new PrintRunnable(i, nThread)); threads.add(thread); thread.start(); } //等待线程结束 threads.forEach(t-> { try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); } static class PrintRunnable implements Runnable{ private int seq;//当前线程序号 private int nThread;//线程总数 public PrintRunnable(int seq,int nThread) { this.seq = seq; this.nThread=nThread; } @Override public void run() { while(true && eachStartNumber<=100){ while (nextPrintThreadSeq!=seq){ LockSupport.parkNanos(100);//停顿等待 } lock.lock(); if(nextPrintThreadSeq!=seq){//再次判断 lock.unlock(); continue; } int n=eachStartNumber; for(int i=0; i<3 & n<=100; i++,n++){ System.out.println("threadSeq: "+seq+", number: "+n); } //修改状态 eachStartNumber+=3; nextPrintThreadSeq=(seq+1)%nThread; lock.unlock(); } } } }
三、附其他人的实现
public class SemaphoreOneHundred { static final Semaphore sem = new Semaphore(1); static int state = 0; static int count = 0; static class ThreadA implements Runnable { @Override public void run() { try { while (count <= 100) { while (state % 3 != 0) { sem.release(); } sem.acquire(); for (int j = 0; j < 3 && count<100; j++) { count++; System.out.println("A " + count); } state++; sem.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadB implements Runnable { @Override public void run() { try { while (count <= 100) { while (state % 3 != 1) { sem.release(); } sem.acquire(); for (int j = 0; j < 3 && count<100; j++) { count++; System.out.println("B " + count); } state++; sem.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadC implements Runnable { @Override public void run() { try { while (count <= 100) { while (state % 3 != 2) { sem.release(); } sem.acquire(); for (int j = 0; j < 3 && count<100; j++) { count++; System.out.println("C " + count); } state++; sem.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Thread(new ThreadA()).start(); new Thread(new ThreadB()).start(); new Thread(new ThreadC()).start(); } }
人生没有彩排,每一天都是现场直播