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

 

 

 

posted @ 2020-04-25 09:29  timfruit  阅读(1662)  评论(0编辑  收藏  举报