我今天自己写了一下这个小程序这个题目的要求是 :
有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.   

    虽然你的get 和 set 方法都是同步的,但是两个get 和两个set 方法是可以同时进行的,从而导致pfull为-1,最后导致所有线程死锁。
      

  2.   

    那需要怎么改一下,才能让两个get方法或者set方法禁止同时进行呢指教一下  谢谢了
      

  3.   

    使用一个Vector,里面存储橘子或者苹果的对象(当size() < 10),在使用Vector的时候synchronized
      

  4.   

    大家能敲点代码,演示一下就举只有 两个家庭的例子 f1,m1,s1,d1
                            f2,m2,s2,d2我现在越来越糊涂了  大家帮个忙
      

  5.   

    add some code into your "get(),set()"
    satatic Vector vector=new Vector(10);  //class  variable 
    such as:  synchronized(vector.size()...) {
    .....//  do something with your
    }
      

  6.   

    q.putOrange(q.orange);
    不能保证q.orange的同步吧?public synchronized void putOrange(int i)改成下面的样子可以吗?
    public synchronized int putOrange()返回值是q.orange。
      

  7.   

    package test;public 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) {
    int apple = q.putApple();
    System.out.println(Thread.currentThread().getName()
    + " put one apple: the number of apple in the plate:"
    + apple);
    }
    }
    }class Mother extends Thread {
    Plate q; Mother(Plate q) {
    this.q = q;
    } public void run() {
    while (true) {
    int orange= q.putOrange();
    System.out.println(Thread.currentThread().getName()
    + " put one orange:the number of orange in the plate:"
    + 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 { private int apple = 0;
    private int orange = 0;
    private int pFull = 10; public synchronized int putApple() { while(!Thread.currentThread().isInterrupted()){
    if( pFull > 0){
    apple++;
    pFull--;
    break;
    }else{
    try {
    wait();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    notifyAll();
    return apple;
    } public synchronized int getApple() {
    while (apple <= 0 ) {
    try {
    wait();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    pFull++;
    apple--;
    notifyAll();
    return apple+1;
    } public synchronized int putOrange() {
    while(!Thread.currentThread().isInterrupted()){
    if( pFull > 0){
    orange++;
    pFull--;
    break;
    }else{
    try {
    wait();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    notifyAll();
    return orange;
    } public synchronized int getOrange() {
    while (orange <= 0 ) {
    try {
    wait();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    pFull++;
    orange--;
    notifyAll();
    return orange+1;
    }
    }
      

  8.   

    哪有这样控制同步的?
    开始没东西时2种(8个)get线程都被block,2种(8个)put线程竞争。假设其中一个putApple得胜,将放入1苹果并唤醒其他线程,继续竞争,若此时某个getOrange获胜,注意到将从wait代码块后面执行,于是程序将拿取一个桔子明显的逻辑错误。办法:
    在plate定义两个list(数组或者Integer也可),一个放桔子一个放苹果,用这两个东西来分别控制两对get/put方法。
      

  9.   

    试试看,不一定符合你的要求!
    public class ThreadTest
    {
    public static void main(String[] args)
    {
    Fruits q = new Fruits();

    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
    {
    Fruits fruit;
    Father(Fruits fruit)
    {
    this.fruit = fruit;
    }

    public void run()
    {
    while(true)
    {
    fruit.setApple();
    System.out.println(Thread.currentThread().getName() + 
    " put one apple: the number of apple in the plate:" + fruit.appleNumber +
    "the number of full in the plate:" + fruit.full);
    }
    }
    }class Mother extends Thread
    {
    Fruits fruit;
    Mother(Fruits fruit)
    {
    this.fruit = fruit;
    }

    public void run()
    {
    while(true)
    {
    fruit.setOrange();
    System.out.println(Thread.currentThread().getName() + 
    " put one oranger: the number of orange in the plate:" + fruit.orangeNumber +
    "the number of full in the plate:" + fruit.full);
    }
    }
    }class Son extends Thread
    {
    Fruits fruit;
    Son(Fruits fruit)
    {
    this.fruit = fruit;
    }

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

    public void run()
    {
    while(true)
    {
    fruit.getApple();
    System.out.println(Thread.currentThread().getName() + 
    " get one apple: the number of apple in the plate:" + fruit.appleNumber +
    "the number of full in the plate:" + fruit.full);
    }
    }
    }class Fruits
    {
    int appleNumber = 0;
    int orangeNumber = 0;
    int full = 0;

    public synchronized int setApple()
    {
    if(full < 10 && full >= 0 && appleNumber < 10)
    {
    appleNumber += 1;
    full++;
    }
    return appleNumber;
    }

    public synchronized int getApple()
    {
    if(full >= 1 && full <=10 && appleNumber >= 1)
    {
    appleNumber -= 1;
    full--;
    }
    return appleNumber;
    }

    public synchronized int setOrange()
    {
    if(full < 10 && full >= 0 && orangeNumber < 10)
    {
    orangeNumber += 1;
    full++;
    }
    return orangeNumber;
    }

    public synchronized int getOrange()
    {
    if(full >= 1 && full <=10 && orangeNumber >= 1)
    {
    orangeNumber -= 1;
    full--;
    }
    return orangeNumber;
    }

    public synchronized int getFull()
    {
    return appleNumber + orangeNumber;
    }
    }