Java 多线程连续打印ABC

时间:2022-08-26 18:35:54

1. 利用synchronized

思路: 

打印A时,必须先拿到 B,C锁, 打印完了之后,释放A锁,然后打印B的线程拿到A锁后就可以打印B,依次循环。

public class MythreadPrinter implements Runnable {
    private String name;
    private Object prev;
    private Object self;


    @Override
    public void run() {
        int count = 3;
        while (count>0){
            synchronized (prev){
                synchronized (self){
                    System.out.println(name);
                    count--;
                    self.notify();
                }
                try {
                    prev.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws Exception{
        Object a = new Object();
        Object b = new Object();
        MythreaPrinter pa = new MythreaPrinter("A",b,a);
        MythreaPrinter pb = new MythreaPrinter("B",a,b);

        new Thread(pa).start();
        Thread.sleep(100);
        new Thread(pb).start();
        Thread.sleep(100);
    }
}

2.利用lock

public class MythreadPrinter_lock {
    private Lock lock = new ReentrantLock();

    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();

    public String cur_name = "A";
    public static void main(String[] args) {
        MythreadPrinter_lock myPrinter = new MythreadPrinter_lock();

        ExecutorService es = Executors.newFixedThreadPool(3);
        es.submit(myPrinter.new PrinterA());
        es.submit(myPrinter.new PrinterB());
        es.submit(myPrinter.new PrinterC());
        es.shutdown();
    }


    public class PrinterA implements Runnable{
        @Override
        public void run() {
            for (int i = 1; i <= 5; i++) {
                lock.lock();
                try {
                    while(cur_name != "A"){
                        try {
                            conditionA.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("第"+i+"次打印"+cur_name);
                    cur_name = "B";
                    conditionB.signal();
                }catch (Exception e){

                }finally {
                    lock.unlock();
                }
            }
        }
    }
    public class PrinterB implements Runnable{
        @Override
        public void run() {
            for (int i = 1; i <= 5; i++) {
                lock.lock();
                try {
                    while(cur_name != "B"){
                        try {
                            conditionB.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("第"+i+"次打印"+cur_name);
                    cur_name = "C";
                    conditionC.signal();
                }catch (Exception e){

                }finally {
                    lock.unlock();
                }
            }
        }
    }
    public class PrinterC implements Runnable{
        @Override
        public void run() {
            for (int i = 1; i <= 5; i++) {
                lock.lock();
                try {
                    while(cur_name != "C"){
                        try {
                            conditionC.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("第"+i+"次打印"+cur_name);
                    cur_name = "A";
                    conditionA.signal();
                }catch (Exception e){

                }finally {
                    lock.unlock();
                }
            }
        }
    }
}