黑马程序员技术交流社区

标题: 多线程求教 [打印本页]

作者: 柳超    时间: 2014-7-15 17:34
标题: 多线程求教
  1. class Student
  2. {
  3.         boolean flag=true;
  4.         String name;
  5.         private String sex;
  6.         public void set(String name,String sex)
  7.         {
  8.                 this.name=name;
  9.                 this.sex=sex;
  10.         }
  11.         public void show()
  12.         {
  13.                 System.out.println("------"+this.name+"-----------"+this.sex);
  14.         }
  15.        
  16. }
  17. class In implements Runnable
  18. {
  19.         Student stu;
  20.         boolean bool1=true;
  21.         In(Student stu)
  22.         {
  23.                 this.stu=stu;
  24.         }
  25.         public void run()
  26.         {
  27.                 while(true)
  28.                 {
  29.                         synchronized(stu)
  30.                         {
  31.                                 if(stu.flag)
  32.                                 {
  33.                                         try {
  34.                                                 stu.wait();
  35.                                         } catch (InterruptedException e) {
  36.                                                 // TODO Auto-generated catch block
  37.                                                 e.printStackTrace();
  38.                                         }
  39.                                         }
  40.                                         if(bool1)
  41.                                         {
  42.                                                 stu.set("lucy", "girl");
  43.                                                 bool1=false;
  44.                                         }
  45.                                         else
  46.                                         {
  47.                                                 stu.set("李四","男");
  48.                                         }
  49.                                
  50.                                 stu.flag=false;
  51.                                 stu.notify();
  52.                         }
  53.                 }
  54.         }
  55. }
  56. class Out implements Runnable
  57. {
  58.         Student stu;
  59.         private String sex;
  60.         Out(Student stu)
  61.         {
  62.                 this.stu=stu;
  63.         }
  64.         public void run()
  65.         {
  66.                         synchronized(stu)
  67.                         {
  68.                                 if(!stu.flag)
  69.                                 {
  70.                                         try {
  71.                                                 stu.wait();
  72.                                         } catch (InterruptedException e)
  73.                                         {
  74.                                                 // TODO Auto-generated catch block
  75.                                                 e.printStackTrace();
  76.                                         }
  77.                                         }
  78.                                                 while(true)
  79.                                                 {
  80.                                                        
  81.                                                         {
  82.                                                                 stu.show();
  83.                                                                 stu.flag=true;
  84.                                                                 stu.notify();
  85.                                                         }
  86.                                                 }
  87.                                
  88.                                
  89.                 }
  90.                        
  91.                
  92.         }
  93.        
  94. }
  95. class Study
  96. {
  97.         public static void main(String[] args)
  98.         {
  99.                
  100.                 System.out.println("start");
  101.                 Student stu= new Student();
  102.                 In in =new In(stu);
  103.                 Out out =new Out(stu);
  104.                 new Thread(in).start();
  105.                 new Thread(out).start();
  106.         }
  107. }
复制代码

求教  那里要改,  输出给果是   无限的    ------null-----------null
作者: 柳超    时间: 2014-7-15 19:34
自顶!没有人来看看吗
作者: fantacyleo    时间: 2014-7-15 19:59
柳超 发表于 2014-7-15 19:34
自顶!没有人来看看吗

额,这么长的代码,你最好先讲一下你要实现什么功能
作者: 黄宝宝    时间: 2014-7-15 20:15
  1. <div class="blockcode"><blockquote>package cn.main;

  2. class Student
  3. {
  4.         boolean flag=false;//这里应该是false,如果是true的话,一开始生产者就等待了,当然输出null.
  5.         String name;
  6.         private String sex;
  7.         public void set(String name,String sex)
  8.         {
  9.                 this.name=name;
  10.                 this.sex=sex;
  11.         }
  12.         public void show()
  13.         {         try {
  14.                         Thread.sleep(10);//让子弹停一会。
  15.                 } catch (InterruptedException e) {
  16.                        
  17.                         e.printStackTrace();
  18.                 }
  19.                 //得到当前运行的线程名称
  20.                 System.out.println(Thread.currentThread().getName()+"------"+this.name+"-----------"+this.sex);
  21.         }
  22.         
  23. }
  24. class In implements Runnable
  25. {
  26.         Student stu;
  27.         boolean bool1=true;
  28.         In(Student stu)
  29.         {
  30.                 this.stu=stu;
  31.         }
  32.         public void run()
  33.         {
  34.                 while(true)
  35.                 {
  36.                         synchronized(stu)
  37.                         {
  38.                                 if(stu.flag)
  39.                                 {
  40.                                         try {
  41.                                                 stu.wait();
  42.                                         } catch (InterruptedException e) {
  43.                                                 // TODO Auto-generated catch block
  44.                                                 e.printStackTrace();
  45.                                         }
  46.                                  }
  47.                                 
  48.                                                 if(bool1)
  49.                                                 {
  50.                                                         stu.set("lucy", "girl");
  51.                                                         bool1=false;
  52.                                                         stu.show();
  53.                                                 }
  54.                                                 else
  55.                                                 {
  56.                                                         stu.set("李四","男");
  57.                                                         bool1=true;
  58.                                                         stu.show();
  59.                                                 }
  60.                                      
  61.                                 stu.flag=true;
  62.                                 stu.notify();
  63.                         
  64.                                   }
  65.                                 
  66.                 }
  67.         }
  68. }
  69. class Out implements Runnable
  70. {
  71.         Student stu;
  72.         private String sex;
  73.         Out(Student stu)
  74.         {
  75.                 this.stu=stu;
  76.         }
  77.         public void run()
  78.         {
  79.                         synchronized(stu)
  80.                         {
  81.                                 while(true)//while应该放在这儿
  82.                         {
  83.                                 if(!stu.flag)
  84.                                 {
  85.                                         try {
  86.                                                 stu.wait();
  87.                                         } catch (InterruptedException e)
  88.                                         {
  89.                                                 // TODO Auto-generated catch block
  90.                                                 e.printStackTrace();
  91.                                         }
  92.                                 }
  93.                               
  94. //                                while(true){
  95.                                                         
  96.                                                         {
  97.                                                                 stu.show();
  98.                                                                 stu.flag=false;
  99.                                                                 stu.notify();
  100.                                                         }
  101.                                                 }
  102.                                 
  103.                                 
  104.                 }
  105.                         
  106.                
  107.         }
  108.         
  109. }
  110. class Study
  111. {
  112.         public static void main(String[] args)
  113.         {
  114.                
  115.                 System.out.println("start");
  116.                 Student stu= new Student();
  117.                 In in =new In(stu);
  118.                 Out out =new Out(stu);
  119.                 new Thread(in).start();
  120.                 new Thread(out).start();
  121.         }
  122. }
复制代码




作者: 柳超    时间: 2014-7-15 20:42

  1. class Student
  2. {
  3.         boolean flag=false;
  4.         String name;
  5.         private String sex;
  6.         public void set(String name,String sex)
  7.         {
  8.                 this.name=name;
  9.                 this.sex=sex;
  10.         }
  11.         public void show() throws InterruptedException
  12.         {
  13.                 Thread.sleep(10);
  14.                 System.out.println("------"+this.name+"-----------"+this.sex);
  15.         }
  16.        
  17. }
  18. class In implements Runnable
  19. {
  20.         private Student stu;
  21.         boolean bool1=true;
  22.         In(Student stu)
  23.         {
  24.                 this.stu=stu;
  25.         }
  26.         public void run()
  27.         {
  28.                 while(true)
  29.                 {
  30.                         synchronized(stu)
  31.                         {
  32.                                 if(stu.flag)
  33.                                 {
  34.                        
  35.                                         try {stu.wait();} catch (InterruptedException e)
  36.                                         {
  37.                                                 // TODO Auto-generated catch block
  38.                                                 e.printStackTrace();}
  39.                                         }
  40.                                 }
  41.                                 while(true)
  42.                                 {
  43.                                         int x=0;
  44.                                        
  45.                                                 if(x%2==0)
  46.                                                 {
  47.                                                 stu.set("lucy", "girl");
  48.                                                 bool1=false;
  49.                                                 }
  50.                                                 else
  51.                                                 {
  52.                                                         bool1=true;
  53.                                                         stu.set("李四","男");
  54.                                                        
  55.                                                 }
  56.                                                 stu.flag=true;
  57.                                                
  58.                                                 x=x+1;
  59.                                                 stu.notify();
  60.                                 }
  61.                        
  62.                 }
  63.         }
  64. }
  65. class Out implements Runnable
  66. {
  67.         private Student stu;
  68.         private String sex;
  69.         Out(Student stu)
  70.         {
  71.                 this.stu=stu;
  72.         }
  73.         public void run()
  74.         {
  75.                         synchronized(stu)
  76.                         {
  77.                                 while(true)
  78.                                 {
  79.                                 if(!stu.flag)      
  80.                                 {
  81.                                         try {stu.wait();} catch (InterruptedException e)
  82.                                         {
  83.                                                 // TODO Auto-generated catch block
  84.                                                
  85.                                         }
  86.                                 }
  87.                                                
  88.                                                        
  89.                                                         {
  90.                                                                 try {
  91.                                                                         stu.show();
  92.                                                                 } catch (InterruptedException e) {
  93.                                                                         // TODO Auto-generated catch block
  94.                                                                         e.printStackTrace();
  95.                                                                 }
  96.                                                                 stu.flag=false;
  97.                                                                 stu.notify();
  98.                                                         }
  99.                                                
  100.                                
  101.                                                 }
  102.                 }
  103.                        
  104.                
  105.         }
  106.        
  107. }
  108. class Study
  109. {
  110.         public static void main(String[] args)
  111.         {
  112.                
  113.                 System.out.println("start");
  114.                 Student stu= new Student();
  115.                 new Thread(new In(stu)).start();
  116.                 new Thread(new Out(stu)).start();
  117.         }
  118. }
复制代码

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
        at java.lang.Object.notify(Native Method)
        at In.run(Test.java:60)
        at java.lang.Thread.run(Unknown Source)


这个是多线程的练习       一个线程输入  一个线程输出     用  flag  控制   输入一次  就 输出一次两组名字交替输入  输出
作者: 柳超    时间: 2014-7-15 20:43
fantacyleo 发表于 2014-7-15 19:59
额,这么长的代码,你最好先讲一下你要实现什么功能

这个是多线程的练习       一个线程输入  一个线程输出     用  flag  控制   输入一次  就 输出一次两组名字交替输入  输出
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
         at java.lang.Object.notify(Native Method)
         at In.run(Test.java:60)
         at java.lang.Thread.run(Unknown Source)这个是报错
作者: 柳超    时间: 2014-7-15 20:46
黄宝宝 发表于 2014-7-15 20:15

这样写就 不是一个线程控制输入 一个线程控制输出 了! 我这个是想 两个线程 一个控制输入一个控制输出
然后通过 flag 控制 wait 和notify执行
作者: tianleboy    时间: 2014-7-15 22:08
你这个代码有同步的对象不一样,而且你在show方法中直接打印System.out.println(name +"...."+sex); 不用加this。如果你加this的话,调用对象是stu的值传不到。      第二个问题就是在set方法中没有加同步。set方法中有共享数据,应该加同步。 最后一个就是Out方法不用加同步代码,因为在Out中只有一条共享数据。也就是show方法,既然在show()加上了同步函数,就不用造Out写同步代码块。
  1. class Student{
  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 {
  8.                                 wait();
  9.                         } catch (InterruptedException e) {
  10.                                 // TODO Auto-generated catch block
  11.                                 e.printStackTrace();
  12.                         }
  13.                 }
  14.                 this.name = name;
  15.                 this.sex = sex;
  16.                 flag =true;
  17.                 this.notify();
  18.         }
  19.         public synchronized void show(){
  20.                 if(!flag){
  21.                         try {
  22.                                 wait();
  23.                         } catch (InterruptedException e) {
  24.                                 // TODO Auto-generated catch block
  25.                                 e.printStackTrace();
  26.                         }
  27.                 }
  28.                 System.out.println(name +"...."+sex);
  29.                 flag = false;
  30.                 notify();
  31.         }
  32. }
  33. class In implements Runnable{
  34.         private Student stu;
  35.         In(Student stu){
  36.                 this.stu = stu;
  37.         }
  38.         public void run(){
  39.                 int x =0;
  40.                 while(true){
  41.                         synchronized(stu){
  42.                                
  43.                                 if(x==0){
  44.                                         stu.set("lucy", "girl");
  45.                                 }else{
  46.                                         stu.set("李四", "男");
  47.                                 }
  48.                                 x = (x+1)%2;
  49.                         }
  50.                 }
  51.         }
  52.        
  53. }
  54. class Out implements Runnable{
  55.         private Student stu;
  56.         Out(Student stu ) {
  57.                 this.stu = stu;
  58.         }
  59.         public void run(){
  60.                 while(true){
  61.                      stu.show();
  62.                         }
  63.                 }
  64.        
  65. }
  66. public class Study {
  67.         public static void main(String[] args){
  68.                 Student stu = new Student();
  69.                 new Thread(new In(stu)).start();
  70.                 new Thread(new Out(stu)).start();
  71.         }

  72. }
复制代码

作者: 黄宝宝    时间: 2014-7-15 22:11
柳超 发表于 2014-7-15 20:46
这样写就 不是一个线程控制输入 一个线程控制输出 了! 我这个是想 两个线程 一个控制输入一个控制输出
...

Thread-0:是输入的线程任务。Thread-1:是输出的线程任务。

注意上面我发的代码,有些修改了没有注释给你看,你看看。

A)R58E~RI87{N{BZGL(0G@I.jpg (128.74 KB, 下载次数: 61)

A)R58E~RI87{N{BZGL(0G@I.jpg

作者: 柳超    时间: 2014-7-16 17:00
黄宝宝 发表于 2014-7-15 22:11
Thread-0:是输入的线程任务。Thread-1:是输出的线程任务。

注意上面我发的代码,有些修改了没有注释给 ...

线程1只输入  线程2 只输出  我的意思
作者: fantacyleo    时间: 2014-7-16 17:16
你的代码不符合你的思考逻辑。你的flag初始化为true,此时学生的姓名和性别都为空。按理说应该让in在flag=true时调用set方法,让out在flag=true时等待。但代码中却在flag=true时让in等待,导致set方法调用不了。同时flag=true时out又判定为不等待,所以打印出null。然后就是无限循环问题。out的run方法中:
  1. while(true)
  2. {
  3.     {
  4.         stu.show();
  5.         stu.flag=true;
  6.         stu.notify();
  7.     }
  8. }
复制代码

这里虽然notify了另一个线程,但notify本身不会放弃同步锁,而你的out线程又在这里死循环,始终拿着锁不放,导致无限循环null,null




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2