5-1-Java多线程-练习-妖的出现和解决
来源:互联网 发布:苹果mac好用吗 编辑:程序博客网 时间:2024/04/30 09:48
妖的出现和解决
需求
- 资源有姓名和性别。
- 两个线程,
- 一个负责给姓名和性别赋值,
一个负责获取姓名和性别的值。
要求1,运行一下,解决程序的 “妖”的问题。
分析过程:
加入同步,必须保证同一个锁,解决妖的问题。要求2,实现正确数据的间隔输出 如
张飞–男
rose–女女女
张飞–男
rose–女女女要求3,对代码进行重构。
将name,sex私有化,资源类提供对其访问的方法。要求4,将程序改成JDK1.5的Lock Condition接口。
代码示例-需要分析的代码
代码
//描述资源。class Resource{ String name; String sex;}//赋值线程任务class Input implements Runnable{ private Resource r; // private Object obj = new Object(); Input(Resource r)//任务一初始化就必须有要处理的资源。 { this.r = r; } public void run() { int x = 0; while(true) { if(x==0) { r.name = "张飞"; r.sex = "男"; } else { r.name = "rose"; r.sex = "女女女女"; } x = (x+1)%2;//实现切换。 } }}//获取值线程任务class Output implements Runnable{ private Resource r ; // private Object obj = new Object(); Output(Resource r) { this.r = r; } public void run() { while(true) { System.out.println(r.name+"....."+r.sex); } }}class ThreadTest2{ public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); }}
运行结果
张飞.....男rose.....女女女女rose.....女女女女张飞.....女女女女张飞.....女女女女rose.....男rose.....女女女女rose.....女女女女张飞.....女女女女rose.....女女女女rose.....女女女女张飞.....男张飞.....男rose.....女女女女
分析
操作共享数据 name 和 sex
假设在–>处切换CPU执行权
if(x==0){ r.name = "张飞"; --> r.sex = "男";}else{ r.name = "rose"; --> r.sex = "女女女女";}
解决问题1
要求1,运行一下,解决程序的 “妖”的问题。
分析过程:
加入同步,必须保证同一个锁,解决妖的问题
代码示例
注意使用resouce做锁.(同步输入输出两个动作)
class Resource{ String name; String sex;}//赋值线程任务class Input implements Runnable{ private Resource r; // private Object obj = new Object(); Input(Resource r)//任务一初始化就必须有要处理的资源。 { this.r = r; } public void run() { int x = 0; while(true) { synchronized(r) { if(x==0) { r.name = "张飞"; r.sex = "男"; } else { r.name = "rose"; r.sex = "女女女女"; } } x = (x+1)%2;//实现切换。 } }}//获取值线程任务class Output implements Runnable{ private Resource r ; // private Object obj = new Object(); Output(Resource r) { this.r = r; } public void run() { while(true) { synchronized(r) { System.out.println(r.name+"....."+r.sex); } } }}class ThreadTest2{ public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); }}
运行结果
rose.....女女女女rose.....女女女女rose.....女女女女rose.....女女女女rose.....女女女女rose.....女女女女rose.....女女女女rose.....女女女女张飞.....男张飞.....男张飞.....男张飞.....男张飞.....男张飞.....男张飞.....男张飞.....男
解决问题2
- 要求2,实现正确数据的间隔输出 如
张飞–男
rose–女女女
张飞–男
rose–女女女
代码
使用等待唤醒机制,使用flag作为判断是否等待
class Resource{ String name; String sex; //定义标记, boolean flag = false;}//赋值线程任务class Input implements Runnable{ private Resource r; // private Object obj = new Object(); Input(Resource r)//任务一初始化就必须有要处理的资源。 { this.r = r; } public void run() { int x = 0; while(true) { synchronized(r) { if(r.flag) try{r.wait();}catch(InterruptedException e){} if(x==0) { r.name = "张飞"; r.sex = "男"; } else { r.name = "rose"; r.sex = "女女女女"; } r.flag = true; r.notify(); } x = (x+1)%2;//实现切换。 } }}//获取值线程任务class Output implements Runnable{ private Resource r ; // private Object obj = new Object(); Output(Resource r) { this.r = r; } public void run() { while(true) { synchronized(r) { if(!r.flag) try{r.wait();}catch(InterruptedException e){} System.out.println(r.name+"....."+r.sex); r.flag = false; r.notify(); } } }}class ThreadTest2_2{ public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); }}
解决问题3
- 要求3,对代码进行重构。
将name,sex私有化,资源类提供对其访问的方法。
代码示例
class Resource{ private String name; private String sex; //定义标记, private boolean flag = false; //赋值功能。 public synchronized void set(String name,String sex) { if(flag) try{this.wait();}catch(InterruptedException e){} this.name = name; this.sex = sex; flag = true; this.notify(); } //获取值。 public synchronized void out() { if(!flag) try{this.wait();}catch(InterruptedException e){} System.out.println(name+"------"+sex); flag = false; this.notify(); }}//赋值线程任务class Input implements Runnable{ private Resource r; Input(Resource r)//任务一初始化就必须有要处理的资源。 { this.r = r; } public void run() { int x = 0; while(true) { if(x==0) { r.set("张飞","男"); } else { r.set("rose","女女女女"); } x = (x+1)%2;//实现切换。 } }}//获取值线程任务class Output implements Runnable{ private Resource r ; Output(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}class ThreadTest2_3{ public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); }}
解决问题4
要求4,将程序改成JDK1.5的Lock Condition接口。
Lock替换了 同步函数或者同步代码块。
Condition替代了 监视器方法,将监视器方法从锁上分离出来,单独封装成Condition对象。
代码示例
class Resource{ private String name; private String sex; //定义标记, private boolean flag = false; //先创建锁对象。 private final Lock lock = new ReentrantLock(); //通过锁对象获取监视器对象。 private Condition con = lock.newCondition(); //赋值功能。 public void set(String name,String sex) { lock.lock(); try{ if(flag) try{con.await();}catch(InterruptedException e){} this.name = name; this.sex = sex; flag = true; con.signal(); }finally{ lock.unlock(); } } //获取值。 public void out() { lock.lock(); try{ if(!flag) try{con.await();}catch(InterruptedException e){} System.out.println(name+"------"+sex); flag = false; con.signal(); }finally{ lock.unlock(); } }}//赋值线程任务class Input implements Runnable{ private Resource r; Input(Resource r)//任务一初始化就必须有要处理的资源。 { this.r = r; } public void run() { int x = 0; while(true) { if(x==0) { r.set("张飞","男"); } else { r.set("rose","女女女女"); } x = (x+1)%2;//实现切换。 } }}//获取值线程任务class Output implements Runnable{ private Resource r ; Output(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}class ThreadTest2_4{ public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); }}
0 0
- 5-1-Java多线程-练习-妖的出现和解决
- Java多线程-死锁的出现和解决
- java多线程练习1
- 黑马程序员-java的多线程的练习
- java基础--26.死锁问题的出现和解决
- 简单的 java 多线程编程练习。
- JAVA编程思想第四版-多线程的练习答案之练习5
- JAVA编程思想第四版-多线程的练习答案之练习1
- 多进程和多线程的练习笔记
- java基础- 多线程抽奖- 练习总结1
- java多线程练习
- Java多线程练习
- Java多线程练习二
- Java多线程练习三
- java学习练习(每个程序员1小时内必须解决的5个编程问题)
- 多线程死锁问题分析和解决[java]
- JAVA基础再回首(二十四)——多线程的概述、实现方式、线程控制、生命周期、多线程程序练习、安全问题的解决
- 一个多线程的练习
- .gitignore中增加过滤规则不起作用的解决方法
- 浅谈 Observable和Observer 观察者模式
- 3-3-Java多线程-案例-银行存钱&同步函数
- golang https服务简单介绍
- 4-1-JDK1.5-Lock接口
- 5-1-Java多线程-练习-妖的出现和解决
- teamviewer一些按键冲突
- Java Arrays.asList()方法详解
- sessionStorage 、localStorage 和 cookie 之间的区别
- amr转MP3(ffmpeg问题记录)
- 欢迎使用CSDN-markdown编辑器
- 类和对象的区别
- Java 按指定概率生成由字母、数字、特殊符号组成的密码
- 栈(数组简单实现)