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