For my thesis I'm working on a Discrete Event System Simulator. The simulation consists in a set of SimulatorThread extends Thread
whose action consist in scheduling Event
s to the Simulator
. Each SimulatorThread
interracts with the Simulator
through the SimulatorInterface
.
public abstract class SimulatorThread extends Thread {
private SimulatorInterface si;
public SimulatorThread(SimulatorInterface si) {
this.si = si;
}
...
}
public final class Simulator {
private ExecutorService exec;
...
public void assignThread(SimulatorThread... stList) {
...
}
}
Before the simulation begins, each SimulatorThread
is assigned to the Simulator
, then the Simulator
will execute each thread through exec.execute(simulatorThread)
. My problem is that in some part of the code i need to get a reference to the current running SimulatorThread
, but the instruction (SimulatorThread) Thread.currentThread()
gives a cast execption. Infact the output of System.out.print(Thread.currentThread().getClass())
is class java.lang.Thread
, but I would like that the output is class SimulatorThread
which can be obtained by running the thread using the instruction simulatorThread.start()
instead of using the executor. So I thought that the problem is in writing an ad-hoc ThreadFactory
that return an instance of SimulatorThread
.
Infact I tried to use the trivial SimulatorThreadFactory extends ThreadFactory
:
public class SimulatorThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
return new SimulatorThread(new SimulatorInterface());
}
}
and with this I obtained the previously cited output 'class SimulatorThread'. The problem is that when I call 'exec.execute(simulatorThread)', the parameter has an attribute 'SimulatorInterface' to which I need to get access, but I can't becaues the parameter of the method 'newThread' is a 'Runnable'. I expose here a wrong code that I hope expresses what I mean better than how I explain in words:
public class SimulatorThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
SimulatorInterface si = r.getSimulatorInterface(); // this is what
// I would like
// the thread factory
// to do
return new SimulatorThread(si);
}
}
So, how can I access to attribute 'SimulatorInterface' of the 'SimulatorThread' inside the method newThread
in order to create a SimulatorThread
if its paramater is a Runnable
?
If I understand your needs, the right way to do this is to not extend Thread
but to implement Runnable
. Then all of the benefits of your own class hierarchy can be enjoyed:
public abstract class SimulatorRunnable extends Runnable {
protected SimulatorInterface si;
public SimulatorRunnable(SimulatorInterface si) {
this.si = si;
}
}
public final class Simulator extends SimulatorRunnable {
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
// here you can use the si
si.simulate(...);
}
}
Then you submit your simulator to your thread-pool:
Simulator simulator = new Simulator(si);
...
exec.submit(simulator);
My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption
You should not be passing a Thread
into an ExecutorService
. It is just using it as a Runnable
(since Thread
implements Runnable
) and the thread-pool starts its' own threads and will never call start()
on your SimulatorThread
. If you are extending Thread
then you need to call thread.start()
directly and not submit it to an ExecutorService
. The above pattern of implements Runnable
with an ExecutorService
is better.