JAVA 多線程打印的幾種方法


在面試中遇到了這個問題 ,這個問題主要考面試者的多線程相關的知識,包括但不限於wait/notify 鎖 Volatile變量3個方面。

3個線程 循環打印ABC 10次

第一種實現 Volatile 實現 依靠共同的state變量來保證 需要輪詢


public class ThreadForDemo {
    private static volatile int threestate=0;
    static class MyThread extends Thread{
        int state;
        MyThread(int state){
            this.state = state;
        }
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                    while (true){
                        if(threestate%3==state){
                            break;
                        }
                    }
                    System.out.println((char)('A'+state));
                    threestate++;
            }

        }
    }
    public static void main(String[] args) {
        MyThread one = new MyThread(0);
        MyThread two = new MyThread(1);
        MyThread three = new MyThread(2);
        one.start();
        two.start();
        three.start();
    }
}

第二種實現 基於 wait/notify范式來實現

wait/ notify 基本上是這樣的

while(條件不成立){
obj.wait();
}
obj.notifyall();

具體實現如下 利用共同的obj 來達到控制的目的 速度比較慢

public class ThreadForDemo {
    static class MyThread implements Runnable {
        Printer printer;
        char words='A';

        public MyThread(Printer printer, char words) {
            this.printer = printer;
            this.words = words;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (printer){
                    while(words!= printer.getWords()){
                        try {
                            printer.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }

                    }
                    printer.print();
                    printer.next();
                    printer.notifyAll();
                }
            }
        }
    }
    static class Printer {
        char words = 'A';
        void print(){
            System.out.println(words);
        }
        void next(){
            switch (words){
                case 'A': words = 'B';
                break;
                case 'B': words = 'C';
                break;
                case 'C': words = 'A';
                break;
            }
        }
        char getWords(){
            return words;
        }
    }
    public static void main(String[] args) {
        Printer printer = new Printer();
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.execute(new MyThread(printer,'A'));
        executorService.execute(new MyThread(printer,'B'));
        executorService.execute(new MyThread(printer,'C'));
        executorService.shutdown();
    }
}

利用 JUC 中的condition 來完成 和 wait / notify方法差不多的效果 區別在與Condition 可以創建多個

public class ThreadForDemo {
    ReentrantLock lock = new ReentrantLock();
    Condition conditionA = lock.newCondition();
    Condition conditionB = lock.newCondition();
    Condition conditionC = lock.newCondition();
    int commonstate = 0;
    class MyThread implements  Runnable{
        int state;

        public MyThread(int state) {
            this.state = state;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                try {
                    switch (state){
                        case 0 :{
                            while (commonstate!=0){
                                conditionA.await();
                            }
                            System.out.println((char)('A'+state));
                            commonstate=1;
                            conditionB.signal();
                            break;
                        }
                        case 1:{
                            while (commonstate!=1){
                                conditionB.await();
                            }
                            System.out.println((char)('A'+state));
                            commonstate=2;
                            conditionC.signal();
                            break;
                        }
                        case 2:{
                            while (commonstate!=2){
                                conditionC.await();
                            }
                            System.out.println((char)('A'+state));
                            commonstate=0;
                            conditionA.signal();
                            break;
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }

            }
        }
    }
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        ThreadForDemo threadForDemo = new ThreadForDemo();
        executorService.execute(threadForDemo.new MyThread(0));
        executorService.execute(threadForDemo.new MyThread(1));
        executorService.execute(threadForDemo.new MyThread(2));
        executorService.shutdown();
    }
}


免責聲明!

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



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