A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 大漠孤烟 中级黑马   /  2014-5-1 14:55  /  1728 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

package com.itheima.thread.demo;



public class ResTest {

        /**
         * 1.线程间的通讯:多个线程处理同一资源,但是任务不同
         */

        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Res r=new Res();
               
                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 Res{
        String name;
    String sex;
       
}
       //输入
        class Input implements Runnable{
                //Res rs=new Res();
                private Res r;
                Input(Res r){ //初始化动作传人要操作的内容
                   this.r=r;
                }
                @Override
                public void run() {
               
                        int x=0;
                        while(true){
                                if(x==0){
                                        r.name="小强";
                                        r.sex="男";
                                }else{
                                        r.name="小红";
                                        r.sex="女";
                                }
                                x=(x+1)%2;
                        }
                       
                }
                //System.out.println(r.name+"........"+r.sex);
        }
    //输出
        class Output implements Runnable{
                //Res rs=new Res();
                private Res r;
                Output(Res r){ //初始化传人要操作的内容
                   this.r=r;
                }
                @Override
                public void run() {
                        System.out.println(r.name+"........"+r.sex);
                       
                }
        }

//打印结果:小强........女
看老师视频敲得,怎么回这样的结果,应该是两个线程切换执行吧,求解。。。

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1

查看全部评分

4 个回复

倒序浏览
本帖最后由 NewDemo 于 2014-5-1 15:50 编辑

因为Output类中的run方法没有循环,当然就只能看到一个结果了啊
  1. package day2;

  2. public class Test0 {
  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 // TODO Auto-generated method stub
  8.                 Res r=new Res();
  9.         
  10.         Input in=new Input(r);
  11.         Output out=new Output(r);
  12.         
  13.         Thread t1=new Thread(in);
  14.         Thread t2=new Thread(out);
  15.         
  16.         t1.start();
  17.         t2.start();
  18.         }

  19. }

  20.     /**
  21.      * 1.线程间的通讯:多个线程处理同一资源,但是任务不同
  22.      */

  23.             // TODO Auto-generated method stub
  24.             


  25. class Res{
  26.     String name;
  27. String sex;
  28.    
  29. }
  30.    //输入
  31.     class Input implements Runnable{
  32.             //Res rs=new Res();
  33.             private Res r;
  34.             Input(Res r){ //初始化动作传人要操作的内容
  35.                this.r=r;
  36.             }
  37.             @Override
  38.             public void run() {
  39.             
  40.                     int x=0;
  41.                     while(true){
  42.                             if(x==0){
  43.                                     r.name="小强";
  44.                                     r.sex="男";
  45.                             }else{
  46.                                     r.name="小红";
  47.                                     r.sex="女";
  48.                             }
  49.                             x=(x+1)%2;
  50.                     }
  51.                     
  52.             }
  53.             //System.out.println(r.name+"........"+r.sex);
  54.     }
  55. //输出
  56.     class Output implements Runnable{
  57.             //Res rs=new Res();
  58.             private Res r;
  59.             Output(Res r){ //初始化传人要操作的内容
  60.                this.r=r;
  61.             }
  62.             @Override
  63.             public void run() {
  64.                     while(true)
  65.                     System.out.println(r.name+"........"+r.sex);//将这句话放进循环里就可以了。
  66.             }
  67.     }
复制代码





因为你的线程没有进行安全性处理,所以肯定出现问题,并不会按照交替打印的,贴上安全处理过的代码
  1. class Res{
  2.         private String name;
  3.         private String sex;
  4.         private boolean flag = false;

  5.         public synchronized void set(String name,String sex){
  6.                 if(flag)
  7.                         try{this.wait();}catch(Exception e){}
  8.                 this.name = name;
  9.                
  10.                 this.sex = sex;
  11.                 flag = true;
  12.                 this.notify()
  13.         }
  14.         public synchronized void out(){
  15.                 if(!flag)
  16.                         try{this.wait();}catch(Exception e){}
  17.                 System.out.println(name+"........"+sex);
  18.                 flag = false;
  19.                 this.notify();
  20.         }
  21. }

  22. class Input implements Runnable{
  23.         private Res r ;
  24.         Input(Res r){
  25.                 this.r = r;
  26.         }
  27.         public void run(){
  28.                 int x = 0;
  29.                 while(true){
  30.                         if(x==0)                                
  31.                                 r.set("mike","man");                                
  32.                         else        
  33.                                 r.set("丽丽","女女女女女");                                
  34.                         x = (x+1)%2;
  35.                 }
  36.         }
  37. }

  38. class Output implements Runnable{
  39.         private Res r ;
  40.         
  41.         Output(Res r){
  42.                 this.r = r;
  43.         }
  44.         public void run(){
  45.                 while(true){
  46.                         r.out();
  47.                 }
  48.         }
  49. }
复制代码




评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1 赞一个!

查看全部评分

回复 使用道具 举报
多线程在共享变量的时候,一定保证变量使用的安全性。上面的例子中,当线程t1正在设置共享变量时,t2抢到了CPU的运行时间,便把t1还没有设置完全的两个变量都输出来了,这样就造成输出结果是一团糟的。为了防止这种结果,必须采用同步技术。最简单的方式是在对设置变量和输出变量的两个函数进行同步,即在方法面前均加上synchronized关键字。
回复 使用道具 举报
//用synchronized加锁容易引起死锁,往往打印个一行或者一两行就不动了。
//下面的实现方案采用的是lock和condition的实现方式,锁及时进行释放,能够出现连续打印的效果

import java.util.concurrent.locks.*;

public class ResTest {
        public static void main(String[] args) {
                Res r = new Res();
                Input in = new Input(r);
                Output out = new Output(r);
                Thread t1 = new Thread(in);
                Thread t2 = new Thread(out);
                t1.start();
                t2.start();
        }
}

/*
* 1、将设置值和打印值的方法抽取到Res类中
* 2、在Res类中加锁
*/
class Res {
        private String name;
        private String sex;
        private boolean flag = false;
        private Lock lock = new ReentrantLock();
        private Condition con1 = lock.newCondition();
        private Condition con2 = lock.newCondition();

        public void set() {
                lock.lock();
                int x = 0;
                try {
                        while(true){
                                while (flag) {
                                        try {
                                                con1.await();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }
                                if (x == 0) {
                                        this.name = "小强";
                                        this.sex = "男";
                                } else {
                                        this.name = "小红";
                                        this.sex = "女";
                                }
                                System.out.println("set:"+this.name + "........" + this.sex);
                                x = (x + 1) % 2;
                                con2.signal();
                                flag = true;
                        }
                } finally {
                        lock.unlock();
                }
        }

        public void out() {
                lock.lock();
                try {
                        while(true){
                                while (!flag) {
                                        try {
                                                con2.await();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }
                                System.out.println("out:"+this.name + "........" + this.sex);
                                con1.signal();
                                flag = false;
                        }
                } finally {
                        lock.unlock();
                }
        }
}

// 输入
class Input implements Runnable {
        private Res r;

        Input(Res r) {
                this.r = r;
        }

        public void run() {
                r.set();
        }
}

class Output implements Runnable {
        private Res r;

        Output(Res r) {
                this.r = r;
        }

        public void run() {
                r.out();
        }
}

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 赞一个!

查看全部评分

回复 使用道具 举报
多谢各位啦,粗心一时没有考虑安全问题,操作共享变量要synchronized同步函数。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马