• 多线程顺序打印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();
        }
    }

     

     

    人生没有彩排,每一天都是现场直播
  • 相关阅读:
    LeetCode
    算法
    GitHub
    GitHub
    git
    将博客搬家至CSDN
    base64与图片互转
    windows下mongodb数据库搭建过程遇到问题
    mongodb数据插入语句与navicat导入mongodb的json结构
    Visual C++安装失败解决:Error 0x80240017: Failed to execute MSU package.
  • 原文地址:https://www.cnblogs.com/timfruit/p/12771602.html
Copyright © 2020-2023  润新知