0

我正在尝试制作一个充当家具厂的多线程程序......例如,它需要有 3 个钉子、2 块木头和 1 块胶水才能制作 1 张桌子。我制作了胶水、木头和钉子类(作为 Thread 类的扩展)

现在,按照我制作的方式,它没有编译错误,但是当它运行时,我在 thread.start() 处得到一个 IlegalThreadState 异常。这是我的主要()

public class Main 
{
public static int mueble = 0; 
public static void main(String[] args) throws InterruptedException 
{
    Semaphore smain = new Semaphore(1);
    Madera m = new Madera();
    Formica f = new Formica();
    Clavo c = new Clavo();
    boolean b = true;
    while(b)
    {
        Random rand = new Random();
        int r = (int)(rand.nextDouble()*6+0);
        if(r < 1)
        {
            smain.acquire();
            f.start();
        }
        else if ((r>1)&&(r<3))
        {
            smain.acquire();
            m.start();
        }
        else 
        {
            smain.acquire();
            c.start();
        }
        if (mueble == 30)
        {
            b = false;
        }
        smain.release();
    }

}
}

不要介意西班牙语。我认为问题可能出在每个线程的 run() 部分,在这里(三个类几乎相同)

@Override
public void run()
{
    try {
        sclavo.acquire();
        System.out.println("Llega 1 clavo");
        System.out.println("Hay " + (3-sclavo.availablePermits()) + " clavo(s)");
        if((sclavo.availablePermits()==0)&&(Madera.smadera.availablePermits()==0)&&(Formica.sformica.availablePermits()==0))
                {
                    System.out.println("Se ha creado 1 mueble");
                    Main.mueble++;
                    System.out.println("Hay" + Main.mueble + "mueble(s)");
                    Formica.sformica.release(1);
                    sclavo.release(3);
                    Madera.smadera.release(2);
                }
    } catch (InterruptedException ex) {
        Logger.getLogger(Clavo.class.getName()).log(Level.SEVERE, null, ex);
    }
}

任何帮助都会很棒!

4

1 回答 1

2

您无法重新启动线程。查看Thread.start. 它说:

多次启动一个线程是不合法的。

您在一个循环中一遍又一遍地启动相同的线程。相反,您应该查看其ExecutorService工作原理并改为使用它。一个好的多线程系统是基于作业的,每个作业要么是 aRunnable要么是Callable. 当您Runnable只想运行某些任务并且它没有任何输出时使用(特别是,如果作业基本上返回void)。Callable当你的工作确实有回报时,你会使用它。在 SO 和其他地方有很多关于如何使用ExecutorService和相关类的示例。

如果你别无选择只能手动使用线程,那么你需要在每个循环上创建并启动一个新线程,例如:

new Formica().start();

Formica而不是一遍又一遍地启动同一个实例。

于 2012-10-12T18:26:55.937 回答