(原创)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
原因是导入的第三方库中也引入了项目中存在的相同名称的库,导致产生冲突
随机推荐
- 编写一个python脚本功能-备份
版本一 解决方案当我们基本完成程序的设计,我们就可以编写代码了,它是对我们的解决方案的实施.版本一例10.1 备份脚本——版本一 #!/usr/bin/python # Filename: backu ...
- JavaScript的Cookie操作
JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的. 而cookie是运行在客户端的,所以可以用JS来设置cookie. 假 设有这样 ...
- Knockout 系列
由于近期要做的项目要兼容到IE6,原来的angular框架已经不能满足现在的兼容性要求. 解决方案: 1. 放弃框架,改为库 2. UI库采用 Knockout,css 3. css库 采用 boot ...
- CodeForces 625D Finals in arithmetic
神奇的构造题,我的思路比较奇葩.搞了好久,看到WA on 91我绝望了,然后自己造数据,找到了错误,总算是AC了,现在是凌晨0:24分,看到AC之后,感动China! 我写的代码无比的长.....应该 ...
- 关于eclipse创建Maven项目创建的问题
1.问题: 为什么Maven Update Project JDK变回1.5 解释:官方文档 The Compiler Plugin is used to compile the sources of ...
- 【转】HashMap实现原理分析
1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1 ...
- leetcode--010 Linked List Cycle II
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAApAAAACICAIAAADfzUzYAAANeklEQVR4nO3dQa7bthbG8W4mK/A+so
- 最基本的SQL语法/语句
DDL—数据定义语言(Create,Alter,Drop,DECLARE) DML—数据操纵语言(Select,Delete,Update,Insert) DCL—数据控制语言(GRANT,REVOK ...
- ARM处理器简介
参考: http://www.arm.com/zh/products/processors/instruction-set-architectures/index.php 1.ARM核演变图 2.AR ...
- 【转】安卓Java的虚拟机区别
Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野.它对内存的高效使用,和在低速CPU上表现出的高性能,确实令 ...