用java来实现线程之间的wait、notify()通信
2015-09-28 10:46
597 查看
两个线程一个为Input向资源中写入数据,一个为output从资源中读取数据。当写入线程写入数据的时候,首先要对资源加锁,如果资源中没有数据,则向资源中写入数据,写入完毕后释放锁(notify),如果资源有数据,则等待,直到资源中没有数据为止才继续写入数据。
特别需要注意的的写入线程中标红的部分,else不能加上。因为两个线程都在操作同一个资源,r.isflag()为true判断完毕后,判断完毕后,r.flag可能已经为false。此时会出现与要求不符的情况。
public void run() {
int x = 0;
while (true) {
synchronized (r) {
if (r.isFlag())//如果已经有数据
{
try {
r.wait();//已经阻塞线程了 阻塞之后 肯定为f.flag一定为false
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{//如果加上else,那么会出现一种情况if判断时为true,判断完毕后,r.flag已经为false。
//会出现数据不一致的情况 因此不需要加else
if (x % 2 == 0) {
r.setName("类兴邦");
r.setSex("男");
}else
{
r.setName("张红");
r.setSex("女");
}
x=++x%2;
r.setFlag(true);
r.notify();//通知其他获取对象锁的线程
}
}
}
}
正确的代码如下:
特别需要注意的的写入线程中标红的部分,else不能加上。因为两个线程都在操作同一个资源,r.isflag()为true判断完毕后,判断完毕后,r.flag可能已经为false。此时会出现与要求不符的情况。
public void run() {
int x = 0;
while (true) {
synchronized (r) {
if (r.isFlag())//如果已经有数据
{
try {
r.wait();//已经阻塞线程了 阻塞之后 肯定为f.flag一定为false
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{//如果加上else,那么会出现一种情况if判断时为true,判断完毕后,r.flag已经为false。
//会出现数据不一致的情况 因此不需要加else
if (x % 2 == 0) {
r.setName("类兴邦");
r.setSex("男");
}else
{
r.setName("张红");
r.setSex("女");
}
x=++x%2;
r.setFlag(true);
r.notify();//通知其他获取对象锁的线程
}
}
}
}
正确的代码如下:
package WN; public class Input extends Thread { private Res r; public Input(Res r) { this.r = r; } @Override public void run() { int x = 0; while (true) { synchronized (r) { if (r.isFlag())//如果已经有数据 { try { r.wait();//已经阻塞线程了 阻塞之后 肯定为f.flag一定为false } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }//如果加上else,那么会出现一种情况if判断时为true,判断完毕后,r.flag已经为false。 //会出现数据不一致的情况 因此不需要加else if (x % 2 == 0) { r.setName("类兴邦"); r.setSex("男"); }else { r.setName("张红"); r.setSex("女"); } x=++x%2; r.setFlag(true); r.notify();//通知其他获取对象锁的线程 } } } public static void main(String[] args) { Res r = new Res(); Input in = new Input(r); Output out = new Output(r); in.start(); out.start(); } }
package WN; public class Res { private String name; private String sex; private boolean flag=false; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } }
package WN; public class Output extends Thread{ private Res r; public Output (Res r) { this.r = r; } @Override public void run() { int x = 0; while (true) { synchronized (r) { if (r.isFlag())//如果已经有数据 { System.out.println(r.getName()+","+r.getSex()); r.setFlag(false);//已经取出数据 r.notify(); }else//没有数据 { try { r.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }
相关文章推荐
- eclipse环境搭建(JDK+虚拟机)
- 【springmvc+mybatis项目实战】杰信商贸-27.POI由HSSF升级为XSSF
- 定时任务用到的cron时间表达式 CronTrigger
- myeclipse部署时An internal error occurred 错误的几种情况
- 数据处理----Java数据处理之RMI
- Spring与Mybatis整合,jar版本要求
- 配置文件web.xml中整合SpringMVC
- java String 类的内存分配
- [] == ![]涉及的运算符及类型转换
- Spring Boot——开发新一代Spring应用
- Java核心技术第3章(5)
- Eclipse安装Maven插件
- spring mvc模拟用户增删改查以及登录和上传文件的相关流程
- java 申明对象和new一个对象如: People peple和People people=new People()
- spring进阶
- Mybatis 接口编程+Spring注解版加载容器
- 常用加密算法的Java实现总结
- JavaSE--- 设计模式、JDK5.0新特性、JDK7.0新特性
- easyui ajax请求获取SpringMVC @ResponseBody返回Json数据
- 关于如何解决Eclipse闪退进不去的问题