JUC之定制化线程通信(Lock)

172 阅读1分钟

前言

还是以前的填坑,说好了要把java多线程的内容完完整整搞一遍(人麻了东西不少,这个东西漏了)

需求

这个需求很简单,其实是小爷的java作业,刚好需要用到这个东西。

题目是这样的,创建三个线程,老师线程上课,大喊三声上课,学生线程小明本来要睡觉滴,然后被老师吵醒了然后上课,顺便把隔壁睡觉的小红叫醒。

实现效果是这样滴

image.png

Lock

想要完成这个那么就需要那啥,用到那个LOCK 先前随便聊过,但是那啥,没说那个是可以直接通信的。

private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();

这个condition其实也是相当于那个lock,但是这个是可以被别的线程唤醒通信的。知道了这个,我们就可以编码了。

代码设计

这个简单。首先是老师,学生类。


class student{
    String name;

    public student(String name) {
        this.name = name;
    }

    public void startclass(){
        System.out.println(name+"上课");
    }
}
class teacher{
    public teacher(String name) {
        this.name = name;
    }

    String name;
    public void teacher(){
        for (int i = 0; i < 3; i++) {
            System.out.println("上课");
        }
    }
}

之后是我们的场景,我们要上课嘛,同时我们要那个通信的话,也是应该把他们整合在一起,lock最好是类变量,这样就不会导致,繁琐的参数传递,和线程无法获取当前锁的各种问题。


class INClass{
    private Lock lock = new ReentrantLock();
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    private int Flag=1;

    public void Teacher(teacher teacher){
        try {
            lock.lock();
            teacher.teacher();
            Flag = 2;
            c2.signal();
        }finally {
            lock.unlock();
        }
    }

    public void Student1(student student){
        try {
            lock.lock();
            while (Flag!=2){
                c2.await();//await()是一个放锁的过程,需要轮询等待
            }
            System.out.println("不睡10分钟了");
            student.startclass();
            Flag = 3;
            c3.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    public void Student2(student student){
        try {
            lock.lock();
            while (Flag!=3){
                c3.await();
            }
            System.out.println("被1吵醒了");
            student.startclass();

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

这个就是我们搭建的场景 接下来就是代码测试喽

class Test2{
    public static void main(String[] args) {
        INClass inClass = new INClass();
        new Thread(()->{
            inClass.Teacher(new teacher("老师"));
        }).start();
        new Thread(()->{
            inClass.Student1(new student("学生1"));
        }).start();
        new Thread(()->{
            inClass.Student2(new student("学生2"));
        }).start();
    }
}

ok,今天就水一点吧~