线程查杀和运行问题

时间:2013-11-29 10:41:31

标签: java multithreading

现在我正在使用线程,试图学习如何以正确的方式对其进行编码:)现在我的代码出现了问题。

package main;
import java.util.Random;

public class Pick extends Thread
{
private Controll controll;

 public Pick(Controll controll)
{
  this.controll = controll;
}

public void run()
{

  while (true)
  {
     int itemID = generateItemID();

     try {
        controll.Pick(itemID);
    } catch (InterruptedException e) {

        e.printStackTrace();
    };

     System.out.println("Item: " + itemID + " picked!");
     System.out.println(controll.getFill() + " of " + controll.getPalletSize());

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }


  }
}

public int generateItemID()
{
  Random randomGenerator = new Random();
  int itemID = randomGenerator.nextInt(100);
  return itemID;
}

}

和其他班级

package main;
import java.util.ArrayList;

public class Controll
{
private ArrayList<Integer> ItemID;
private int PalletID;
private int PalletSize;
private int Fill;
private volatile boolean running = true;

 public Controll()
{
   this.ItemID = new ArrayList<>();
}

public synchronized void Pick(int itemID) throws InterruptedException

{
   while(running)
   {
     if (getPalletSize() == Fill)
     {
         terminate();
        System.out.println("Pallet is full!");
        for(int i = 0; i <ItemID.size();i++)
        {
            System.out.println(ItemID.get(i));
        }

       wait();

     }
     else
     {


  ItemID.add(itemID);
  Fill++;
  notifyAll();
     }
}
}

public synchronized int getPalletID()
{
   return PalletID;
}

public synchronized int getPalletSize()
{
    return PalletSize;
}

public synchronized void setPalletSize(int size)
{
    this.PalletSize = size;
}

public synchronized int getFill()
{
    return Fill;
}

public synchronized void setFill(int size)
{
    this.Fill = size;
}

public void terminate() {
    running = false;
}

}

和我的测试班:

package test;

import junit.framework.TestCase;
import main.*;

public class TestC extends TestCase {

   public void test() throws InterruptedException
   {
      Controll controll = new Controll();

      Pick pick = new Pick(controll);
      controll.setPalletSize(10);
      controll.setFill(1);


      pick.start();


      pick.join();



   }

}

结果我得到的是: 托盘已满! 3 3 3 3 3 3 3 3 3

我试图让托盘装满时必须停止向arraylist添加新物品,并且必须显示添加到arraylist中的每一件物品,但它只打印出一个arraylist里面的东西,也许有人可以帮助我解决这个问题?

2 个答案:

答案 0 :(得分:1)

为了正确使用Random,您应该创建一次并选择您需要的次数。

将随机成员更改为类静态成员。并将其置于private Controll controll;private static Random RANDOM_GENERATOR = new Random();

public int generateItemID()
{
  int itemID = RANDOM_GENERATOR.nextInt(100);
  return itemID;
}

在这种情况下,我们创建一次随机但多次使用它。 有关伪数生成器的更多信息,请阅读

答案 1 :(得分:0)

它没有显示你想要的行为,因为当你正在做controll.Pick(itemID);时,它正在调用Controll类中的public synchronized void Pick(int itemID) throws InterruptedException。在此方法中,如果托盘未满,则尝试将项目添加到列表中。 所以当你执行时

while(running)


    {
         if (getPalletSize() == getFill())
         {
             terminate();
            System.out.println("Pallet is full!");
            for(int i = 0; i <this.ItemID.size();i++)
            {
                System.out.println(this.ItemID.get(i));
            }

           wait();

         }
         else
         {


      this.ItemID.add(itemID);
      Fill++;
      notifyAll();
         }
    }
    }

你已经使运行为true,所以它将尝试执行while循环,直到除非运行变为false。在这个while循环中,每次执行其他条件直到运行变为false。因此,它每次都添加相同的itemid并最终托盘变满了。这就是为什么它显示上面的输出。