(原创)Java多线程作业题报java.lang.IllegalMonitorStateException解决
作业:
有一个水池,水池容量500L,一边为进水口,一边为出水口,要求进水放水不能同时进行,水池一旦满了不能继续注水,一旦空了,不能继续放水,进水速度5L/s,放水速度2L/s。
这是我学多线程时做的一道练习题,刚开始对wait()方法存在错误理解导致运行时报异常-----java.lang.IllegalMonitorStateException,修复后,在此把错误写法以及最终正确写法都整理出来。
class Water{
static int litre = 500;
boolean flag=true; //false为可以继续加水,true为可以继续放水
}
class OutPour extends Thread{ //出水类
Water w;
OutPour(Water w){
this.w=w;
}
@Override
public void run() { //正确写法
while(true){
synchronized(w){
if(w.flag==true){ //放水,2L/s
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre-2;
System.out.println("放水中,现在还剩"+w.litre+"升水!");
if(w.litre<=0){ //放空了
w.flag=false;
System.out.println("--------空了!--------");
w.notify();
}
}else{
try {
w.wait();//等加满
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/*
@Override
public void run() { //错误写法
while(true){
if(w.flag==true){ //放水,2L/s
synchronized(w){
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre-2;
System.out.println("放水中,现在还剩"+w.litre+"升水!");
if(w.litre<=0){ //放空了
w.flag=false;
System.out.println("--------空了!--------");
w.notify
}
}
}else{
try {
w.wait();//等加满
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
*/
}
class InPour extends Thread{ //进水类
Water w;
InPour(Water w){
this.w=w;
}
@Override
public void run() { //正确写法
while(true){
synchronized(w){
if(w.flag==false){//加水,5L/s
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre+5;
System.out.println("加水中,现在有"+w.litre+"升水!");
if(w.litre>=500){//加满了
System.out.println("-------满了!-------");
w.flag=true;
w.notify();
}
}else{
try {
w.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/*
@Override
public void run() { //错误写法
while(true){
if(w.flag==false){ //加水,5L/s
synchronized(w){
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre+5;
if(w.litre>=500){ //加满了
System.out.println("-------满了!-------");
w.flag=true;
w.notifyAll();
}
}
}else{
try {
w.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
*/
}
public class Demo11 {
public static void main(String[] args){
Water w = new Water();
OutPour o = new OutPour(w);
InPour i = new InPour(w);
o.start();
i.start();
}
}
run方法在业务逻辑上并没有错,报异常java.lang.IllegalMonitorStateException,是因为wait()方法必须要放在同步代码块中才能使用。把else{}语句也圈到synchronized代码块即可。也奉劝,先把笔记看了之后再敲代码,能为调试省不少时间。。。
(原创)Java多线程作业题报java.lang.IllegalMonitorStateException解决的更多相关文章
- Java多线程编程核心技术---Java多线程技能
基本概念 进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据结构在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,是系统进行资源分配和调度的独立单位.线程可以理解成是在进 ...
- 解决:IDEA unable to import maven project see logs for details问题+java http请求报java.net.SocketException: Permission denied:connect 问题
背景:用IDEA写了一个java发送http请求的maven项目. 运行时,项目报java.net.SocketException: Permission denied:connect问题: 修改po ...
- (1)Java多线程编程核心——Java多线程技能
1.为什么要使用多线程?多线程的优点? 提高CPU的利用率 2.什么是多线程? 3.Java实现多线程编程的两种方式? a.继承Thread类 public class MyThread01 exte ...
- Java多线程编程(1)--Java中的线程
一.程序.进程和线程 程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码.它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编译之后生成的可执行文 ...
- 【java多线程系列】java内存模型与指令重排序
在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...
- java 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())
JAVA中有3种方式可以终止正在运行的线程 ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()方法强行终止线程.但stop()方法已经过期了,不推荐使用 ③使用中断机制i ...
- java多线程基础(二)--java多线程的基本使用
java多线程的基本使用 在java中使用多线程,是通过继承Thread这个类或者实现Runnable这个接口或者实现Callable接口来完成多线程的. 下面是很简单的例子代码: package c ...
- Java多线程系列一——Java实现线程方法
Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2) ...
- grade配置添加java库导致报 java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMerger
原因是导入的第三方库中也引入了项目中存在的相同名称的库,导致产生冲突
随机推荐
- 日志文件 统计 网站PV IP
1. 安装rrdtool yum install rrdtool 2. 创建 rrdtool 数据库 rrdtool create /opt/local/rrdtool/jicki.rrd -s 30 ...
- Run Loop简介
做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一门语言还是需要深层次的了解它,这样才能在使用的时候得心应手,出 ...
- Thinking in scala (4)----阶乘与尾递归
code1: object factorial{ def main(args:Array[String])={ println(factorial(args(0).toInt)) } def fact ...
- Insert Select
有三种用法 1.insert values 2.insert select 3.inser exec
- thinkPHP的学习
1.版本,以3.1为主,因为手册是基于这个的,最新的版本,还没有对应的手册 2.发现一个问题,echo 中文时,出现乱码,而调用模版则正常. 3.写url的注意大小写.index和Index是不同的 ...
- 安卓canvas操作的总结
2014.07.03 使用canvas绘图 需求:公司需要绘制波形图,类似数学上的正弦波,一条是参考值,一条是实际曲线 解决方法:采用canvas绘图.保存为图片,以供导出 这里提供一个学习的demo ...
- [Angular Tutorial]PhoneCat Tutorial App
(注:曾经在<不敢止步>一书中看到学到一个观点,作者认为学习一门技术最好的方法就是翻译某部领域书籍.这里我决定做一次尝试,接下来花1个月左右时间,将Angular Tutorial Pho ...
- OC--初始化UINavigationController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...
- Selenium2(java)selenium常用API 五
上传文件 元素标签是input时上传方式 上传是一个input,对于这种元素是input 的标签可以采用元素的sendKeys()方法来直接赋值,upload.html代码: <html&g ...
- iOS 之 事件响应者链
响应者链表示一系列的响应者对象.事件被交由第一个响应者对象处理,如果第一个响应者不处理,事件就沿着响应者链向上传递,交由下一个响应者(Next responder). View->ViewCon ...