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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何明辉 中级黑马   /  2012-7-25 22:44  /  1707 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何明辉 于 2012-7-27 12:23 编辑

class Common
{
      private String name;
      private int age;
     public static boolean flag=false;
     void set(String name ,int age)
        {
            this.name=name;
            this.age=age;
        }
    String get()
     {
         return name+"...."+age;
       }
}
class In implements Runnable
{
     Common com;
     In(Common com)
    {
        this.com=com;
     }
   public void run()
   {
      int x=0;
       while(true)
       {
           while(!Common.flag)
          {
               if(x==0)com.set("HeMingHui",25);
              else com.set("HeMingSheng",23);
              x=++x%2;
               Common.flag=false;
          }
       }
    }
}
class Out implements Runnable
{
     Common com;
     Out(Common com)
       {
            this.com=com;
       }
      public void run()
      {
           while(true)
            {
                while(Common.flag)
                 {   
                     System.out.println(com.get());
                    Common.flag=true;
                 }
  
            }
      }
}
class InOutDemo1
{
public static void main(String[] args)
{
       Common com=new Common();
       Thread t1=new Thread(new In(com));
      Thread t2=new Thread(new Out(com));
      t1.start();
      t2.start();
  }

上面的程序中实现的功能是:线程t1实现输入信息,线程t2输出信息,在dos中实现交替显示。
  (1)根据对同步的概念的理解我设计上面的程序也能实现相应的功能啊,线程t1和t2通过对flag值的交替改变也能实现同步啊,怎么没有达到预期的效果。
(2)还有就是我看毕老师第十二天第5集的视频上面列子中,列子里面线程t1,t2,t3,t4中t1和t2都在同步函数里面,也就是没有出来,好比老师说的蹲厕所的列子,只要是在里面,不管碰到是sleep()和wait()都会在里面,那么其他线程就不会进去。所以最后结果要么全部是输入,要么全部是输出。因为毕老师第11天第10集就是这么讲的,如果碰到sleep()就出了同步的话,那么第11天10集里面最后加了同步在碰到sleep()后有可能输出结果还会出现0,-1,-2的情况。请高手帮我纠正误区,谢谢!

2 个回复

正序浏览
你上面的代码都没有加synchronized()锁,所以肯定不会同步啦。
一般若要线程t1和t2通过对flag值的交替改变也能实现同步,则需要添加wait() notify()方法等待唤醒;我们课件上的例题你看看
public class Student {
        public String name;
        public int age;
        boolean flag = false;
}
* 设置学生值的线程
*/
public class Input implements Runnable {
        private Student s;       
        //Object obj = new Object();
                public Input(Student  s){
                this.s = s;
        }
        @Override
        public void run() {
                int x = 0;
                while (true) {
                        synchronized (s) { //t1                               
                                //如果有数据,则设置数据这个线程就等待.
                                if(s.flag){
                                        try {
                                                s.wait();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }                               
                                if (x % 2 == 0) {
                                        s.name = "刘德华";
                                        s.age = 50;
                                } else {
                                        s.name = "朱丽倩";
                                        s.age = 45;
                                }                               
                                //有数据
                                s.flag = true;
                                //改变数据的标记后,唤醒输出线程
                                s.notify();  //唤醒对方的同时,本身也可能还有执行权.
                        }
                        x++;
                }
        }
}
* 打印学生信息
*/
public class Output implements Runnable {
        private Student s;       
        //Object obj = new Object();       
        public Output(Student s){
                this.s = s;
        }
        @Override
        public void run() {
                while (true) {
                        synchronized (s) { //t2
                                if(!s.flag){
                                        try {
                                                s.wait();//t2这个线程就bu走了
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }                               
                                System.out.println(s.name + "***" + s.age);
                                //没有数据改标识为false
                                s.flag =  false;
                                //唤醒输入线程
                                s.notify();
                        }
                }
        }
}
public class StudentTest {
                public static void main(String[] args) {
                //创建学生对象,这是一个资源
                Student s = new Student();               
                Input in = new Input(s);
                Output out = new Output(s);               
                Thread t1 = new Thread(in);
                Thread t2 = new Thread(out);               
                t1.start();
                t2.start();               
                //t1,t2带过去进行判断               
        }
}
回复 使用道具 举报

class Common
{
      private String name;
      private int age;
     public static boolean flag=false;
     void set(String name ,int age)
        {
            this.name=name;
            this.age=age;
        }
    String get()
     {
         return name+"...."+age;
       }
}
class In implements Runnable
{
     Common com;
     In(Common com)
    {
        this.com=com;
     }
   public void run()
   {
      int x=0;
       while(true)
       {
           while(!Common.flag)
          {                                               
               if(x==0)com.set("HeMingHui",25);
              else com.set("HeMingSheng",23);
              x=(++x)%2;//这个地方你写错了
               Common.flag=true;//这个地方改成Common.flag= true这样他才会进入
                               //out的里的run()里第二个while循环
          }
       }
    }
}
class Out implements Runnable
{
     Common com;
     Out(Common com)
       {
            this.com=com;
       }
      public void run()
      {
           while(true)
            {
                while(Common.flag)
                                               
                 {   
                     System.out.println(com.get());
                     Common.flag=false;//Common.flag的值改为false这样在叫它进入in循环                 }
  
            }
      }
}
class InOutDemo1
{
public static void main(String[] args)
{
       Common com=new Common();
       Thread t1=new Thread(new In(com));
      Thread t2=new Thread(new Out(com));
      t1.start();
      t2.start();
  
}
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马