- /*
- 这是我写的关于线程间通信的示例。
- 线程间的通信:
- 其实就是多个线程操作同一个资源,但是操作的动作不同。
- 本示例需要定义三个类:
- 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();
-
- }
- }
- //运行结果显示成功解决输入线程和输出线程通信的安全问题。
复制代码
|