Los subprocesos en Java no se inician simultáneamente, sino secuencialmente

Tengo un pequeño problema al escribir un algoritmo multiproceso en Java. Esto es lo que tengo:

public class NNDFS implements NDFS {

//Array of all worker threads
private Thread[] threadArray; 

//Concurrent HashMap containing a mapping of graph-states and 
//algorithm specific state objects (NDFSState)
private ConcurrentHashMap<State, NDFSState> stateStore;

//Whether the algorithm is done and whether a cycle is found
private volatile boolean done;
private volatile boolean cycleFound;


/**
  Constructor that creates the threads, each with their own graph

  @param  file        The file from which we can create the graph
  @param  stateStore  Mapping between graph-states and state belonging to our algorithm
  @param  nrWorkers   Number of working threads we need
 */
public NNDFS(File file, Map<State, NDFSState> stateStore, int nrWorkers) throws FileNotFoundException {
    int i;
    this.stateStore = new ConcurrentHashMap<State, NDFSState>(stateStore);
    threadArray = new Thread[nrWorkers]; 
    for(i=0;i<nrWorkers;i++){
         Graph graph = GraphFactory.createGraph(file);
         threadArray[i] = new Thread(new NDFSRunnable(graph, i));
    }
}

/**
    Class which implements a single thread running the NDFS algorithm
 */
class NDFSRunnable implements Runnable{

    private Graph graph;

    //Neccesary as Java apparently doesn't allow us to get this ID
    private long threadId; 

    NDFSRunnable(Graph graph, long threadId){
         this.graph = graph;
         this.threadId = threadId;
    }

    public void run(){
        try {
            System.out.printf("Thread id = %d\n", threadId);
            //Start by executing the blue DFS for the first graph
            mcdfsBlue(graph.getInitialState(), threadId);
        } catch (CycleFound e) {
            //We must catch all exceptions that are thrown from within our thread
            //If exceptions "exit" the thread, the thread will silently fail
            //and we dont want that. We use 2 booleans instead, to indicate the status of the algorithm

            cycleFound = true;
        }

        //Either the algorithm was aborted because of a CycleFound exception
        //or we completed our Blue DFS without finding a cycle. We are done!
        done = true;
    }

    public void mcdfsBlue(State s, long id) throws CycleFound {
        if(done == true){
           return;
        }
        //System.out.printf("Thread %d begint nu aan een dfsblue\n", id);
        int i;
        int counter = 0;
        NDFSState state = stateStore.get(s);
        if(state == null){
                state = new NDFSState();
                stateStore.put(s,state);
        }
        state.setColor(id, Color.CYAN);
        List<State> children = graph.post(s);
        i = state.incNextBlue();
        while(counter != children.size()){
            NDFSState child = stateStore.get(children.get(i%children.size()));

            if(child == null){
                    child = new NDFSState();
                    stateStore.put(children.get(i % children.size()),child);
            }
            if(child.getLocalColor(id) == Color.WHITE && !child.isRed()){

                mcdfsBlue(children.get(i % children.size()), id);
            }
            i++;
            counter++;
        }
        if(s.isAccepting()){
            state.incRedDFSCount();
            mcdfsRed(s, id);
        }
        state.setColor(id, Color.BLUE);
    }

    public void mcdfsRed(State s, long id) throws CycleFound {
        if(done == true){
            return;
        }
        int i;
        int counter = 0;
        NDFSState state = stateStore.get(s);
        state.setPink(id, true);
        List<State> children = graph.post(s);
        i = state.incNextRed();
        while(counter != children.size()){
            NDFSState child = stateStore.get(children.get(i%children.size()));
            if(child == null){
                    child = new NDFSState();
                    stateStore.put(children.get(i%children.size()),child);
            }
            if(child.getLocalColor(id) == Color.CYAN){
                throw new CycleFound();
            }
            if(!child.isPink(id) && !child.isRed()){
                mcdfsRed(children.get(i%children.size()), id);
            }
            i++;
            counter++;
        }
        if(s.isAccepting()){
            state.decRedDFSCountAndWait();
        }
        state.setRed();
        state.setPink(id, false);
    }

}

public void init() {}

public void ndfs() throws Result {
    int i;
    done       = false;
    cycleFound = false;
    for(i=0;i<threadArray.length;i++){
            System.out.printf("Launch thread %d\n",i);
            threadArray[i].run();
    }

    try {
        for(i=0;i<threadArray.length;i++){
            threadArray[i].join();
        }
    } catch (InterruptedException e) {

    }

    //We want to show the result by throwing an exception (weird, but yeah :-/)
    if (cycleFound) {
      throw new CycleFound();
    } else {
      throw new NoCycleFound();
    }
}                               

}

Sin embargo, cuando ejecuto esto, parece que se llama al primer subproceso, se completa y luego se llama al siguiente, etc. Lo que quiero, obviamente, es que todos los subprocesos se inicien simultáneamente. De lo contrario, el algoritmo tiene muy poco uso ...

¡Gracias por su tiempo/ayuda!

Saludos,

Linus

preguntado el 22 de mayo de 12 a las 14:05

¿Quieres llamar? threadArray[i].start(); en lugar de .run() ? -

¿Lanzar excepciones para devolver un resultado? No te acostumbres a hacer eso, simplemente está... mal. -

@SoboLAN Sí, lo sé, esto es solo una mejora de un marco que nos dieron. Tampoco estamos contentos con eso... -

1 Respuestas

Utiliza threadArray[i].start(); para lanzar tu hilo.

Si utiliza threadArray[i].run();, todo lo que hace es llamar al método normalmente, en el mismo hilo que la persona que llama.

contestado el 22 de mayo de 12 a las 14:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.