/*编写一个Java应用程序,要求有3个线程:studentl、student2和teacher,其中线程studentl准备“睡”20分钟后再开始上课,
线程student2准备“睡”一小时后再开始上课。teacher在输出4句“上课”后,“唤醒”了休眠的线程studentl;
线程studentl被“唤醒”后,负责再“唤醒”休眠的线程student2。*/
class WakeStudent{
public static void main(String[] args){
Wake wake = new Wake();
Thread student1, student2, teacher;
student1 = new Thread(wake);
student1.setName("shuishen1"); //睡神一
student2 = new Thread(wake);
student2.setName("shuishen2"); //睡神二
teacher = new Thread(wake);
teacher.setName("disruptsleep");//睡神杀手。
student1.start();
student2.start();
teacher.start(); //启动三个进程(刚编的时候忘了写,要注意!!!)
}
}class Wake implements Runnable{
public static int alert = 0; //0为安全;1为老师发飙;2为学生student1被叫醒,然后student1不得不叫旁边睡觉的student2 public void run(){
String name = Thread.currentThread().getName();
//线程student1
if(name.equals("shuishen1")){
while (alert == 0) {
System.out.println("睡神一说:先睡20分钟再说,反正这老师也不点名");
try {
wait(); // 如果老师没发飙必须等待
} catch (InterruptedException e){
}
}
while(alert == 1){
System.out.println("睡神一说:我起来听课了,我去叫旁边的睡神二");
notifyAll();
alert = 2;
}
}
//线程student2
if(name.equals("shuishen2")){
if(alert != 2) {
System.out.println("睡神二说:先睡一个小时再说,老师点名了有睡神一叫我起来");
try {
wait(); // 如果睡神一没提醒他则必须等待
} catch (InterruptedException e) {
}
}else{
System.out.println("老师和睡神一都在看我,不好不起来听课了!");
}
}
//线程teacher
if(name.equals("disruptsleep")){
for(int i = 0; i < 4 ;i++){
System.out.println("上课!!!不准睡觉!!!");
}
alert = 1;
//notifyAll();
}
}
}提示出现错误。Exception in thread "shuishen1"上课!不准睡觉!!java.lang.illegalMonitorStateException
at java.lang.object.wait<Native Method>
at java.lang.Object.wait(Object.java:485)
线程student2准备“睡”一小时后再开始上课。teacher在输出4句“上课”后,“唤醒”了休眠的线程studentl;
线程studentl被“唤醒”后,负责再“唤醒”休眠的线程student2。*/
class WakeStudent{
public static void main(String[] args){
Wake wake = new Wake();
Thread student1, student2, teacher;
student1 = new Thread(wake);
student1.setName("shuishen1"); //睡神一
student2 = new Thread(wake);
student2.setName("shuishen2"); //睡神二
teacher = new Thread(wake);
teacher.setName("disruptsleep");//睡神杀手。
student1.start();
student2.start();
teacher.start(); //启动三个进程(刚编的时候忘了写,要注意!!!)
}
}class Wake implements Runnable{
public static int alert = 0; //0为安全;1为老师发飙;2为学生student1被叫醒,然后student1不得不叫旁边睡觉的student2 public void run(){
String name = Thread.currentThread().getName();
//线程student1
if(name.equals("shuishen1")){
while (alert == 0) {
System.out.println("睡神一说:先睡20分钟再说,反正这老师也不点名");
try {
wait(); // 如果老师没发飙必须等待
} catch (InterruptedException e){
}
}
while(alert == 1){
System.out.println("睡神一说:我起来听课了,我去叫旁边的睡神二");
notifyAll();
alert = 2;
}
}
//线程student2
if(name.equals("shuishen2")){
if(alert != 2) {
System.out.println("睡神二说:先睡一个小时再说,老师点名了有睡神一叫我起来");
try {
wait(); // 如果睡神一没提醒他则必须等待
} catch (InterruptedException e) {
}
}else{
System.out.println("老师和睡神一都在看我,不好不起来听课了!");
}
}
//线程teacher
if(name.equals("disruptsleep")){
for(int i = 0; i < 4 ;i++){
System.out.println("上课!!!不准睡觉!!!");
}
alert = 1;
//notifyAll();
}
}
}提示出现错误。Exception in thread "shuishen1"上课!不准睡觉!!java.lang.illegalMonitorStateException
at java.lang.object.wait<Native Method>
at java.lang.Object.wait(Object.java:485)
解决方案 »
- Ire po rt~ Sum ma r y区 很讨厌的问题啊~~~~有图 ~~~~很详细的图片啊!!~希望得到大家的帮助啊!谢谢啊!~
- 请教正则式的写法,检查一行代码是否包括类似于“<%@ include file=”这样的字符串
- 日期解析问题(急),大家帮看一下
- [闭月羞花猫]关于LDAP中各个字段的问题
- JAVA实习的困惑
- this怎么用?
- jsp+postgresql乱码问题?急,大家帮我
- 用java开发fc模拟器有没有可能,在手机上运行呢?
- 谁能说明一下这些都是什么啊?
- 问个很菜的问题!java程序怎么运行?
- java 语音通讯开发
- 急!!!java Swing 如何得到JButton的点击次数!!!谢谢了
线程student2准备“睡”一小时后再开始上课。teacher在输出4句“上课”后,“唤醒”了休眠的线程studentl;
线程studentl被“唤醒”后,负责再“唤醒”休眠的线程student2。*/
class WakeStudent {
public static void main(String[] args) {
Wake wake = new Wake();
Thread student1, student2, teacher;
student1 = new Thread(wake);
student1.setName("shuishen1"); // 睡神一
student2 = new Thread(wake);
student2.setName("shuishen2"); // 睡神二
teacher = new Thread(wake);
teacher.setName("disruptsleep");// 睡神杀手。 student1.start();
student2.start();
teacher.start(); // 启动三个进程(刚编的时候忘了写,要注意!!!)
}
}class Wake implements Runnable {
public static int alert = 0; // 0为安全;1为老师发飙;2为学生student1被叫醒,然后student1不得不叫旁边睡觉的student2 public void run() {
String name = Thread.currentThread().getName();
// 线程student1
if (name.equals("shuishen1")) {
while (alert == 0) {
System.out.println("睡神一说:先睡20分钟再说,反正这老师也不点名");
Thread.yield();
} while (alert == 1) {
System.out.println("睡神一说:我起来听课了,我去叫旁边的睡神二");
alert = 2;
}
}
// 线程student2
if (name.equals("shuishen2")) { if (alert != 2) {
System.out.println("睡神二说:先睡一个小时再说,老师点名了有睡神一叫我起来");
Thread.yield();
}
else {
System.out.println("老师和睡神一都在看我,不好不起来听课了!");
}
}
// 线程teacher
if (name.equals("disruptsleep")) {
for (int i = 0; i < 4; i++) {
System.out.println("上课!!!不准睡觉!!!");
}
alert = 1;
}
}
}
// 商品的库存量
private int goodsCount = 10;
// 得到商品的库存量
public int getGoodsCount(){
return goodsCount;
}
// 出售一件商品
public void sale(){
if(goodsCount <= 0){
System.out.println("商品已经买完,还未进货");
return;
}
System.out.println("购买一件商品");
this.goodsCount--;
}
// 进货
public void incoming(int count){
goodsCount += count;
}
}当某个线程在这家商店购买商品时,先得到商店的互斥锁,并判断商店库存是否大于0,如果大于0则购买商品,否则等待这家商店进货:Shop shop = ...... // 得到这家商店对象的引用
synchronized(shop){
try{
while(shop.getGoodsCount() <= 0){
shop.wait();
}
shop.sale();
}catch(Exception ex){
}
}这其实也很好理解,某人进入一家商店买东西时,商店只对你服务,其他想买东西的人在后面排队,因此认为你得到了互斥锁
如果商品库存大于0,则顺利地买到你想要的东西,而如果商品的库存不够时,你只能等待,并且让商店去干别的事情(比如为在你后面排队的人服务,或者去进货),也就是说你应该释放你的互斥锁,并且等待,这就是调用wait方法的作用。
而当其它线程调用了商店的进货方法之后,并且调用这家商店的notify或notifyAll方法之后,购买商品的线程将被叫醒,并且在wait方法之后继续运行。首先应该要注意到,这三个方法都是 Object 类就已经定义了的,而不是在 Thread 和 Runnable 接口中定义的。也就是说wait、notify、notifyAll 是针对对象,而不是针对类。在如上的例子中,如果商店有几家,则在不同的商店上进行wait时,结果也不一样。另外,在调用wait前要先得到互斥锁,这也好理解,如果没有进行同步,对象的一些状态可能被其它的线程改变还有就是,在调用wait方法时,有一个while循环检查对象的状态。这是因为wait之后,释放了对象的锁,而释放锁之后可能改变对象的状态。比如在前面的例子中,在库存为0时有10个客人在等待购买商品,那么将会有10个线程在等待商店进货,而某次进货线程只进了5件商品,那么在进货线程调用notfiyAll叫醒这10个等待购买商品的线程当中,只有前5个线程能够跳出while循环,后面5个线程还得接着等待。这其实是合理的。