黑马程序员技术交流社区
标题:
线程间通信练习
[打印本页]
作者:
itheima_llt
时间:
2015-4-10 17:50
标题:
线程间通信练习
/*
这是我写的关于线程间通信的示例。
线程间的通信:
其实就是多个线程操作同一个资源,但是操作的动作不同。
本示例需要定义三个类:
1 资源类Resource
2 输入类Input
3 输出类Output
步骤:
1 先写出基本情况
2 找安全问题并修改
*/
/*
//本类定义的资源是,人的数据
class Resource
{
private String name;//私有化人的名字
private String sex;//私有化人的性别
//提供set方法,来访问name和sex
public void set(String name,String sex)
{
this.name = name;
this.sex = sex;
}
//提供get方法来打印name和sex
public void get()
{
System.out.println(name+"......"+sex);
}
}
//本类定义的是往共享数据中存数据
class Input implements Runnable
{
//私有化共享数据
private Resource r;
//利用重载构造函数来传递共享数据
Input(Resource r)
{
this.r = r;
}
//首先覆盖run方法,定义功能:一种情况存入男人,另一种情况存入女人
public void run()
{
//定义一个布尔变量来区分两种情况
boolean flag_in = true;
while(true)
{
if(flag_in)//如果为真,则存入男,张三
{
r.set("张三","男");
flag_in = false;
}
else//如果为假,则存入女,李丽
{
r.set("李丽",".........女");
flag_in = true;
}
}
}
}
//本类定义的是从共享数据中取数据
class Output implements Runnable
{
private Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.get();
}
}
class MyInputOutputDemo
{
public static void main(String[] args)
{
//建立资源对象
Resource r = new Resource();
//建立实习了runnable接口的对象
Input in = new Input(r);
Output out = new Output(r);
//建立线程对象
Thread t1 = new Thread(in);//输入线程
Thread t2 = new Thread(out);//输出线程
//启动线程
t1.start();
t2.start();
}
}
*/
/*
运行结果中存在:
李丽......男
张三...............女
说明了线程通信存在安全问题
什么原因呢??
因为在存数据的同时,还可以取数据。
下面利用上次所学的解决安全问题的办法
*/
/*
//本类定义的资源是,人的数据
class Resource
{
private String name;//私有化人的名字
private String sex;//私有化人的性别
private boolean flag = false;//设置监视器来控制输入输出
//提供set方法,来访问name和sex
public void set(String name,String sex)
{
if(!flag)//监视器为假的时候,存入数据
{
this.name = name;
this.sex = sex;
flag = true;
}
}
//提供get方法来打印name和sex
public void get()
{
if(flag)//监视器为真的时候取出数据
{
System.out.println(name+"......"+sex);
flag = false;
}
}
}
//本类定义的是往共享数据中存数据
class Input implements Runnable
{
//私有化共享数据
private Resource r;
//利用重载构造函数来传递共享数据
Input(Resource r)
{
this.r = r;
}
//首先覆盖run方法,定义功能:一种情况存入男人,另一种情况存入女人
public void run()
{
//定义一个布尔变量来区分两种情况
boolean flag_in = true;
while(true)
{
if(flag_in)//如果为真,则存入男,张三
{
r.set("张三","男");
flag_in = false;
}
else//如果为假,则存入女,李丽
{
r.set("李丽",".........女");
flag_in = true;
}
}
}
}
//本类定义的是从共享数据中取数据
class Output implements Runnable
{
private Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.get();
}
}
class MyInputOutputDemo
{
public static void main(String[] args)
{
//建立资源对象
Resource r = new Resource();
//建立实习了runnable接口的对象
Input in = new Input(r);
Output out = new Output(r);
//建立线程对象
Thread t1 = new Thread(in);//输入线程
Thread t2 = new Thread(out);//输出线程
//启动线程
t1.start();
t2.start();
}
}
*/
/*
运行结果显示:
通过给资源增加监视器,已经解决了存取错误的一个问题。
但是还存在这样的问题:
张三......男
张三......男
张三......男
李丽...............女
这说明还存在安全问题。
这是由于CPU切换造成的。
正确的情况应该是交替输出:
存一个取一个。
那么该怎么解决呢???
Java提供了等待唤醒机制。
下面改动一下程序。
*/
//本类定义的资源是,人的数据
class Resource
{
private String name;//私有化人的名字
private String sex;//私有化人的性别
private boolean flag = false;//设置监视器来控制输入输出
//提供set方法,来访问name和sex
public synchronized void set(String name,String sex)
{
if(flag)//监视器为真的时候,等待
{
try
{
this.wait();
}
catch (Exception e)
{
}
}
this.name = name;
this.sex = sex;
flag = true;
this.notify();//唤醒线程池中的第一个线程
}
//提供get方法来打印name和sex
public synchronized void get()
{
if(!flag)//监视器为假的时候,线程等待
{
try
{
this.wait();
}
catch (Exception e)
{
}
}
System.out.println(name+"......"+sex);
flag = false;
this.notify();//唤醒线程池中的第一个线程
}
}
//本类定义的是往共享数据中存数据
class Input implements Runnable
{
//私有化共享数据
private Resource r;
//利用重载构造函数来传递共享数据
Input(Resource r)
{
this.r = r;
}
//首先覆盖run方法,定义功能:一种情况存入男人,另一种情况存入女人
public void run()
{
//定义一个布尔变量来区分两种情况
boolean flag_in = true;
while(true)
{
if(flag_in)//如果为真,则存入男,张三
{
r.set("张三","男");
flag_in = false;
}
else//如果为假,则存入女,李丽
{
r.set("李丽",".........女");
flag_in = true;
}
}
}
}
//本类定义的是从共享数据中取数据
class Output implements Runnable
{
private Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.get();
}
}
class MyInputOutputDemo
{
public static void main(String[] args)
{
//建立资源对象
Resource r = new Resource();
/*
//建立实现了runnable接口的对象
Input in = new Input(r);
Output out = new Output(r);
//建立线程对象
Thread t1 = new Thread(in);//输入线程
Thread t2 = new Thread(out);//输出线程
//启动线程
t1.start();
t2.start();
*/
//上面的6行代码啊可以简化为2行
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}
}
//运行结果显示成功解决输入线程和输出线程通信的安全问题。
复制代码
作者:
rick1991chen
时间:
2015-4-22 15:24
顶一个!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2