簡體   English   中英

Java中的線程不是同時啟動,而是順序啟動

[英]Threads in Java not launching simultaneously, but sequentially

我在用Java編寫多線程算法時遇到了一些問題。 這是我得到的:

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();
    }
}                               

}

但是,當我運行此程序時,似乎第一個線程被調用,完成,然后另一個線程被調用等等。顯然,我想要的是所有線程同時啟動! 否則該算法幾乎沒有用處...

感謝您的時間/幫助!

問候,

萊納斯

使用threadArray[i].start(); 啟動您的線程。

如果使用threadArray[i].run(); ,它所做的只是在與調用方相同的線程中正常調用該方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM