(原创)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
原因是导入的第三方库中也引入了项目中存在的相同名称的库,导致产生冲突
随机推荐
- Nginx + Apache 反向代理
反向代理负载均衡 使用代理服务器可以将请求转发给内部的Web服务器,使用这种加速模式显然可以提升静态网页的访问速度.因此也可以考虑使用这种技术,让代理服务器将请求均匀转发给多台内部Web服务器之一上, ...
- iOS开发使用MJRefresh进行刷新
1.将MJRefresh下载后,拖进项目 MJRefresh地址: https://github.com/CoderMJLee/MJRefresh 2.添加头文件 #import "MJRe ...
- BZOJ 1257 [CQOI2007]余数之和sum ——Dirichlet积
[题目分析] 卷积很好玩啊. [代码] #include <cstdio> #include <cstring> #include <cmath> #include ...
- nodejs抓取数据一(列表抓取)
纯属初学...有很多需要改进的地方,请多多指点... 目标是抓取58同城 这个大分类下的列表数据: http://cd.58.com/caishui/?PGTID=14397169455980.924 ...
- access 随机选取数据
access随机读取数时 用order by rnd(id) 发现每次获取的数据顺序都是一致的,必须要加上随机数才可以,如下: Random r = new Random(); ...
- 安装pip工具
Python 2.7.9+ and 3.4+ Good news! Python 3.4 (released March 2014) and Python 2.7.9 (released Decemb ...
- oracle关键字(保留字)
其实这个东西可以在oracle 上输入一个sql语句就可以得到: select * from v$reserved_words order by keyword asc; //order 后边不是 ...
- My数据库和Ms数据库的区别
mssql 是微软的那个 SQL Server,运行于windows2000,2003等平台 mysql 是由瑞典mySQL AB 公司开发,目前属于Oracle旗下公司.可运行在windows平台. ...
- bzoj1355——2016——3——15
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1355 题目大意: 1355: [Baltic2009]Radio Transmission ...
- Strut、Spring、Hibernate如何实现资源整合(SSH)呢?
Strut.Spring.Hibernate如何实现资源整合(SSH)呢? 其实很简单,我们从Spring与Hibernate的整合中可以看出来,由Spring的配置文件来管理Hiberbate的配置 ...