前言
还是以前的填坑,说好了要把java多线程的内容完完整整搞一遍(人麻了东西不少,这个东西漏了)
需求
这个需求很简单,其实是小爷的java作业,刚好需要用到这个东西。
题目是这样的,创建三个线程,老师线程上课,大喊三声上课,学生线程小明本来要睡觉滴,然后被老师吵醒了然后上课,顺便把隔壁睡觉的小红叫醒。
实现效果是这样滴
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,今天就水一点吧~