I’m trying to make a multithread program that acts as a furniture factory… For example, it needs to have 3 nails, 2 pieces of wood and 1 piece of glue to make 1 table. I made the glue, wood and nail classes (as extensions of Thread class)
Now, the way I made it, it has no compiling errors, but when it runs, I get an IlegalThreadState exception at the thread.start(). Here’s my Main()
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();
}
}
}
Don’t mind the spanish.
I think the problem might be in the run() section of each thread, here it is (it’s pretty much the same for the three classes)
@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);
}
}
Any help would be great!
You can’t restart a thread. Look at the documentation for
Thread.start. It says:You’re starting the same threads over and over in a loop. Instead, you should look at how
ExecutorServiceworks and use that instead. A good multi-threaded system is job-based, and each job is either aRunnableor aCallable. you useRunnablewhen you just want to run some task and it doesn’t have any output (specifically, if the job essentially returnsvoid). You useCallablewhen your job does return something. There’s plenty of examples here on SO and elsewhere for how to useExecutorServiceand related classes.If you have no choice but to use threads manually, then you need to create and start a new thread on each loop, such as:
As opposed to starting the same
Formicainstance over and over.