JUC之ReentrantLock,Condition;蚂蚁金服 面试题:三个线程交替打印ABC

多线程编程重要的就是标志位Flag,锁,唤醒
多线程编程注意的两个地方:标志位Flag和while
1.判断
2.干活
3.通知+唤醒

之前synchronized锁释放之后线程疯抢争夺资源
但是被Lock,Condition控制后则可以指定线程运行顺序,按需接力,不用疯抢(如果不用Condition依然疯抢)

三个线程交替打印ABC(五次)

package juc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class PrintAbcByOrder {
    public static void main(String[] args) {
        final PrintAbc printAbc = new PrintAbc();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                printAbc.printA();
            }

        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                printAbc.printB();
            }
        }, "B").start();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                printAbc.printC();
            }
        },"C").start();

    }
}
class PrintAbc{
    private ReentrantLock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();
    private int flag = 1;

    public void printA(){
        lock.lock();
        try {
            while (flag != 1){
                condition1.await();
            }
            System.out.println("A");
            flag = 2;
            condition2.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void printB(){
        lock.lock();
        try {
            while (flag != 2){
                condition2.await();
            }
            System.out.println("B");
            flag = 3;
            condition3.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void printC(){
        lock.lock();
        try {
            while (flag != 3){
                condition3.await();
            }
            System.out.println("C");
            flag = 1;
            condition1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}

进阶版 题目:有ABC三个线程,要求线程A打印五次,B10次,C15次,然后,再同样的顺序来两轮。。。共来十轮

package juc;

import sun.awt.windows.ThemeReader;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class ShareResource{

    private int flag = 1;

    private ReentrantLock lock = new ReentrantLock();

    private Condition condition1 = lock.newCondition();

    private Condition condition2 = lock.newCondition();

    private Condition condition3 = lock.newCondition();

    //ctrl+alt+t是try catch

    public void print5(int totalLoop){
        lock.lock();
        try {
            //1.判断
            while (flag != 1){
                condition1.await();
            }
            //干活

            for (int i = 1;i <= 5; i++) {
                System.out.println("线程名字:"+Thread.currentThread().getName()+"\t次数:"+i+"\t轮数:"+totalLoop);
            }

            //唤醒+通知
            flag = 2;
            condition2.signal();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print10(int totalLoop){
        lock.lock();
        try {
            //1.判断
            while (flag != 2){
                condition2.await();
            }
            //干活

            for (int i = 1;i <= 10; i++) {
                System.out.println("线程名字:"+Thread.currentThread().getName()+"\t次数:"+i+"\t轮数:"+totalLoop);
            }

            //唤醒+通知
            flag = 3;
            condition3.signal();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print15(int totalLoop){
        lock.lock();
        try {
            //1.判断
            while (flag != 3){
                condition3.await();
            }
            //干活

            for (int i = 1;i <= 15; i++) {
                System.out.println("线程名字:"+Thread.currentThread().getName()+"\t次数:"+i+"\t轮数:"+totalLoop);
            }

            //唤醒+通知
            flag = 1;
            condition1.signal();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }



}

public class ConditionLockDemo {
    public static void main(String[] args) {

        ShareResource sr = new ShareResource();

        new Thread(()->{
            for(int i = 1 ; i<=10 ; i++){
                sr.print5(i);
            }
        },"A").start();

        new Thread(()->{
            for(int i = 1 ; i<=10 ; i++){
                sr.print10(i);
            }
        },"B").start();

        new Thread(()->{
            for(int i = 1 ; i<=10 ; i++){
                sr.print15(i);
            }
        },"C").start();
    }
}
原创文章 28 获赞 26 访问量 3377

猜你喜欢

转载自blog.csdn.net/Avril___/article/details/104632234