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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM