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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 pengbeilin 于 2015-8-13 14:40 编辑
  1. /* 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。
  2. 当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。
  3. 编程解决猫狗鱼过河问题。

  4. 思路:
  5. 1 第一想法是用多线线程解决
  6. 2 创建动物类和农夫类,然后建立了狗猫鱼的类,动物类中有一个过河的方法,然后用狗猫鱼类集成动物类 并实现过河的方法
  7. 3 创建了一个过河的类实现Runnable接口,通过构造函数接受一个动物的实例,然后在run方法中调用过河方法

  8. 问题是 我加了同步代码块 也实现不了同步 应该是哪里出问题 请各位帮我解答!
  9. */
  10. class text
  11. {
  12.         public static void main(String[] args)
  13.         {
  14.                 //创建了3个线程并启动
  15.                 Thread t2 = new Thread(new goStream(new Cat()));
  16.                 Thread t3 = new Thread(new goStream(new Dog()));
  17.                 Thread t4 = new Thread(new goStream(new Fish()));
  18.                 t2.start();
  19.                 t3.start();
  20.                 t4.start();
  21.         }
  22. }
  23. class goStream implements Runnable
  24. {
  25.         private Animet a;//创建了动物对象用来接收构造函数传进的动物实例
  26.         private Framer f= new Framer();//农夫实例
  27.         Object obj = new Object();//锁
  28.         goStream(Animet a)
  29.         {
  30.                 this.a = a;
  31.         }
  32.         public void run()
  33.         {
  34.                 synchronized(obj)//同步代码
  35.                 {
  36.                         //让任意一种动物和农夫过河
  37.                         a.play();
  38.                         f.play();
  39.                         System.out.println("-----------");
  40.                 }               
  41.         }               
  42. }
  43. //类和方法我都写的比较简陋
  44. class Animet
  45. {        
  46.         void play()
  47.         {
  48.                 System.out.println("动物过河");
  49.         }
  50. }
  51. class Framer
  52. {        
  53.         void play()
  54.         {
  55.                 System.out.println("农夫过河");
  56.         }
  57. }
  58. class Cat extends Animet
  59. {
  60.         void play()
  61.         {
  62.                 System.out.println("猫过河");
  63.         }
  64. }
  65. class Dog extends Animet
  66. {
  67.         void play()
  68.         {
  69.                 System.out.println("狗过河");
  70.         }
  71. }
  72. class Fish  extends Animet
  73. {        
  74.         void play()
  75.         {
  76.                 System.out.println("鱼过河");
  77.         }
  78. }
复制代码

18 个回复

倒序浏览
本帖最后由 liuch111 于 2015-8-13 12:22 编辑

不是同一个锁
我把你的同步锁 改成了 aaa.bbb
回复 使用道具 举报
  1. class text
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 //创建了3个线程并启动
  6.                                 //goStream gs=new goStream();
  7.                 Thread t2 = new Thread(new goStream(new Cat()));
  8.                 Thread t3 = new Thread(new goStream(new Dog()));
  9.                 Thread t4 = new Thread(new goStream(new Fish()));
  10.                 t2.start();
  11.                 t3.start();
  12.                 t4.start();
  13.         }
  14. }

  15. class aaa
  16. {
  17.          static Object bbb=new Object();
  18. }
  19. class goStream implements Runnable
  20. {
  21.         private Animet a;//创建了动物对象用来接收构造函数传进的动物实例
  22.         private Framer f= new Framer();//农夫实例
  23.         Object obj = new Object();//锁
  24.         goStream(Animet a)
  25.         {
  26.                 this.a = a;
  27.         }
  28.         public void run()
  29.         {
  30.                 synchronized(aaa.bbb)//同步代码
  31.                 {
  32.                         //让任意一种动物和农夫过河
  33.                         a.play();
  34.                         f.play();
  35.                         System.out.println("-----------");
  36.                 }               
  37.         }               
  38. }
  39. //类和方法我都写的比较简陋
  40. class Animet
  41. {        
  42.         void play()
  43.         {
  44.                 System.out.println("动物过河");
  45.         }
  46. }
  47. class Framer
  48. {        
  49.         void play()
  50.         {
  51.                 System.out.println("农夫过河");
  52.         }
  53. }
  54. class Cat extends Animet
  55. {
  56.         void play()
  57.         {
  58.                 System.out.println("猫过河");
  59.         }
  60. }
  61. class Dog extends Animet
  62. {
  63.         void play()
  64.         {
  65.                 System.out.println("狗过河");
  66.         }
  67. }
  68. class Fish  extends Animet
  69. {        
  70.         void play()
  71.         {
  72.                 System.out.println("鱼过河");
  73.         }
  74. }
复制代码
回复 使用道具 举报

C:\Users\Administrator\Desktop\java笔记\java>javac text.java

C:\Users\Administrator\Desktop\java笔记\java>java text
猫过河
农夫过河
-----------
狗过河
农夫过河
-----------
鱼过河
农夫过河
-----------



是要这个结果吗?
回复 使用道具 举报
这题明明就是用集合解,怎么会想出多线程的解法啊。
回复 使用道具 举报

蛋疼死了~ 谢谢啦
回复 使用道具 举报
kenfans 发表于 2015-8-13 13:34
这题明明就是用集合解,怎么会想出多线程的解法啊。

Map集合存起来?然后再遍历输出?
回复 使用道具 举报
pengbeilin 发表于 2015-8-13 14:35
Map集合存起来?然后再遍历输出?

他的意思是要你用编程的方式,写出过河的方法。就是用集合的方式判断一个集合中,狗和猫是否同时存在,猫和鱼是否同时存在。河两边用两个集合代替,然后循环判断。农夫基本可以不用管。说明白一点就是:

河这边是集合A,河那边是集合B。
现在集合A扔一个动物给集合B,然后判断集合A是不是同时有狗和猫或者猫和鱼。如果有,过河失败,这个动物就不给B,如果没有。就把这个动物给B,再判断集合B。
集合B也和集合A一样,扔一个动物给集合A。也可以不扔。
每次过河有几种选择,自己集合里的某一个动物扔另一集合,或者不扔。
用for语句嵌套循环就行了。直到集合A的size是0,就过河成功了。这就是代码的思路
回复 使用道具 举报

aaa.bbb是什么意思啊
回复 使用道具 举报
同步搞死人
回复 使用道具 举报
是这样的,你这里的OBJ锁每个线程的对象建立的时候都建立了一个新的OBJ锁,等于每个线程都拥有自己一个独立的锁。可以在goStream内将OBJ定义为静态的,这样OBJ只会加载一次,也就是说每个线程使用的锁都变成同一个了!或者在goStream外重新定义一个锁
回复 使用道具 举报 1 0
如果要解题的话,思路应该是用 list集合去解,考的不是多线程


  1. import java.util.ArrayList;

  2. public class Test10crossriver {
  3.         
  4.         public static void main(String[] args)
  5.         {
  6.                 new Test10crossriver().tohere();
  7.         }
  8.                 //创建一个集合,代表起始点.
  9.                 ArrayList<String> here = new ArrayList<String>();
  10.                 //创建一个集合,代表终点.
  11.                 ArrayList<String> there = new ArrayList<String>();
  12.                 //添加元素.
  13.                 public Test10crossriver()
  14.                 {
  15.                         here.add("Dog");
  16.                         here.add("cat");
  17.                         here.add("fish");
  18.                 }
  19.                 //定义一个方法,用来判断这三个动物之间关系.
  20.                 public boolean isSafe(ArrayList<String> al)
  21.                 {
  22.                         if (al.contains("dog") && al.contains("cat")|| al.contains("cat") && al.contains("fish"))
  23.                         {
  24.                                 return false;
  25.                         }
  26.                         return true;
  27.                 }
  28.                 //定义一个方法,将起点的元素送到终点.
  29.                 public void tohere() {
  30.                         String str = here.get(0);
  31.                         here.remove(str);
  32.                         if (isSafe(here)) {
  33.                                 System.out.println("1农夫带着" + str + "去往对岸,这边还剩下" + here + ",对岸有" + there);
  34.                                 toThere(str);
  35.                         } else {
  36.                                 here.add(str);
  37.                                 tohere();
  38.                         }
  39.                 }
  40.                 //定义一个方法,用来查看终点的元素.
  41.                 public void toThere(String s) {

  42.                                 there.add(s);
  43.                             //如果here没有元素,表示已经成功并结束程序
  44.                                 if(here.isEmpty()){
  45.                                         System.out.println("4农夫,"+there+"都被你带过来了");
  46.                                         return;
  47.                                 }
  48.                             //如果对岸安全,则农夫独自回到本岸,否则带上集合中第一个动物回到本岸
  49.                                 if(isSafe(there)){
  50.                                         System.out.println("2农夫回到原点,对岸有" + there);
  51.                                         tohere();
  52.                                 }else{
  53.                                         String temp=there.get(0);
  54.                                         there.remove(temp);
  55.                                         System.out.println("3农夫带着"+temp+"回到原点,这边有" + here + ",对岸有" + there);
  56.                                         here.add(temp);
  57.                                         tohere();
  58.                                 }
  59.                 }
  60. }
复制代码
回复 使用道具 举报 1 0
呵呵 . .. .   
回复 使用道具 举报
想透脑筋的题目
回复 使用道具 举报
话说这个真的是基础题么??
回复 使用道具 举报
liuch111 发表于 2015-8-13 19:37
如果要解题的话,思路应该是用 list集合去解,考的不是多线程

受教了 谢谢
回复 使用道具 举报
周博文 发表于 2015-8-13 21:31
话说这个真的是基础题么??

是一个基础题~ 不过我没做
回复 使用道具 举报
这个题,有点绕
回复 使用道具 举报
kenfans 发表于 2015-8-13 16:08
他的意思是要你用编程的方式,写出过河的方法。就是用集合的方式判断一个集合中,狗和猫是否同时存在,猫 ...

果然,我也是这个题。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马