layout | title | date | updated | tags | categories | permalink | thumbnail | toc | comment | notag | top | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
5-1-练习-妖的出现和解决 |
2015-10-13 |
2015-10-13 |
|
Java多线程案例 |
true |
true |
false |
false |
- 资源有姓名和性别。
- 两个线程,
-
一个负责给姓名和性别赋值,
-
一个负责获取姓名和性别的值。
-
要求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,运行一下,解决程序的 "妖"的问题。 分析过程: 加入同步,必须保证同一个锁,解决妖的问题
注意使用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,实现正确数据的间隔输出 如 张飞--男 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,对代码进行重构。 将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,将程序改成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();
}
}