VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3180|回复: 19

很有意思的一个题目:关于多线程!!

[复制链接]

2

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
发表于 2020-1-6 19:10:01 | 显示全部楼层 |阅读模式


我今天自己写了一下这个小程序

这个题目的要求是 :
有4对家庭,分别有爸爸,妈妈,儿子,女儿

爸爸们专门负责往盘子里放苹果,妈妈们专门负责往盘子里放橘子,
儿子门专门吃盘子里的橘子;女儿们专门吃盘子里的苹果;

注意;盘子里最多只能有10个水果,而且每次只能放或者取一个水果;

就这么多了,代码在下面,运行出现了点问题,好象有时候 某些方法被访问多次,
有兴趣的可以运行一下代码,帮我分析一下原因,谢谢 了
class ThreadTest
{
       
        public static void main(String[] args)
        {
                Plate q=new Plate();
                Father f1=new Father(q);
                Father f2=new Father(q);
                Father f3=new Father(q);
                Father f4=new Father(q);
               
                Mother m1=new Mother(q);
                Mother m2=new Mother(q);
                Mother m3=new Mother(q);
                Mother m4=new Mother(q);
               
                Son s1=new Son(q);
                Son s2=new Son(q);
                Son s3=new Son(q);
                Son s4=new Son(q);
               
                Daughter d1=new Daughter(q);
                Daughter d2=new Daughter(q);
                Daughter d3=new Daughter(q);
                Daughter d4=new Daughter(q);
               
                f1.start();
                f2.start();
                f3.start();
                f4.start();
               
                m1.start();
                m2.start();
                m3.start();
                m4.start();
               
                s1.start();
                s2.start();
                s3.start();
                s4.start();
               
                d1.start();
                d2.start();
                d3.start();
                d4.start();
        }
}

class Father extends Thread
{
        Plate q;
        Father(Plate q)
        {
                this.q=q;
        }
        public void run()
        {
                while(true)
                {
                        q.putApple(q.apple);
                        System.out.println(Thread.currentThread().getName()+" put one apple:

the number of apple in the plate:"+q.apple);
                }
        }
}
class Mother extends Thread
{
        Plate q;
        Mother(Plate q)
        {
                this.q=q;
        }
        public void run()
        {
                while(true)
                {
                        q.putOrange(q.orange);
                        System.out.println(Thread.currentThread().getName()+" put one

orange:the number of orange in the plate:"+q.orange);
                }
        }
}
class Son extends Thread
{
        Plate q;
        Son(Plate q)
        {
                this.q=q;
        }
        public void run()
        {
                while(true)
                {
                System.out.println(Thread.currentThread().getName()+" get one orange:the

number of orange in the plate:"+q.getOrange());
             }
        }
}
class Daughter extends Thread
{
        Plate q;
        Daughter(Plate q)
        {
                this.q=q;
        }
        public void run()
        {
                while(true)
                {
                System.out.println(Thread.currentThread().getName()+"Daughter get one

apple:the number of apple in the plate:"+q.getApple());
        }
        }
}
class Plate
{
       
        int apple=0;
        int orange=0;
        int pFull=10;
        public synchronized void putApple(int i)
        {
                if(pFull<11 && pFull>0)
                {
                        i++;
                        apple=i;
                        pFull--;
                        notifyAll();
                }
                try
                {
                        wait();
                }
                catch(Exception e)
                {
                        e.printStackTrace();
                }
               
                       
        }
        public synchronized int getApple()
        {
                if(apple<1 || apple>10)
                {
                        try
                        {
                                wait();
                        }
                        catch(Exception e)
                        {
                                e.printStackTrace();
                        }
                       
                }
                pFull++;
               
                notifyAll();
                apple--;
                return apple;
        }
        public synchronized void putOrange(int i)
        {
                if(pFull<11 && pFull>0)
                {
                        i++;
                        orange=i;
                        pFull--;
                        notifyAll();
                }
                try
                {
                        wait();
                }
                catch(Exception e)
                {
                        e.printStackTrace();
                }
               
                       
        }
        public synchronized int getOrange()
        {
                while(orange<1 || orange>11)
                {
                        try
                        {
                                wait();
                        }
                        catch(Exception e)
                        {
                                e.printStackTrace();
                        }
                }
                pFull++;
               
                notifyAll();
                orange--;
                return orange;
        }
}
回复

使用道具 举报

1

主题

51

帖子

32.00

积分

新手上路

Rank: 1

积分
32.00
发表于 2020-1-7 13:39:01 | 显示全部楼层
UP下吧
回复

使用道具 举报

0

主题

1

帖子

1.00

积分

新手上路

Rank: 1

积分
1.00
发表于 2020-1-7 21:49:55 | 显示全部楼层

UP下吧                       
回复

使用道具 举报

2

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
 楼主| 发表于 2020-1-9 19:09:01 | 显示全部楼层
有人帮解释以下么?
回复

使用道具 举报

0

主题

3

帖子

4.00

积分

新手上路

Rank: 1

积分
4.00
发表于 2020-1-10 05:36:01 | 显示全部楼层
mark
回复

使用道具 举报

0

主题

6

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-1-10 21:00:01 | 显示全部楼层
up
回复

使用道具 举报

0

主题

6

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-1-11 01:09:01 | 显示全部楼层
虽然你的get 和 set 方法都是同步的,但是两个get 和两个set 方法是可以同时进行的,从而导致pfull为-1,最后导致所有线程死锁。
回复

使用道具 举报

0

主题

1

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
发表于 2020-1-11 09:01:47 | 显示全部楼层
非常好,学习了!!!
回复

使用道具 举报

2

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
 楼主| 发表于 2020-1-13 17:54:01 | 显示全部楼层
那需要怎么改一下,才能让两个get方法或者set方法

禁止同时进行呢

指教一下  谢谢了
回复

使用道具 举报

0

主题

8

帖子

8.00

积分

新手上路

Rank: 1

积分
8.00
发表于 2020-1-16 14:27:01 | 显示全部楼层
使用一个Vector,里面存储橘子或者苹果的对象(当size() < 10),在使用Vector的时候synchronized
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表