简体   繁体   中英

best way to kill threads in a java environment?

Im currently working on an SSL crawler and I'm wondering which is the best or safest way to kill the spawned threads. In fact, I fork threads based on available URLs fetched from DB. I have a class thread controller which monitors all spawned thread and decide whether to fork more based on URLs availability? I need advice regarding killing thread safely?

here is the thread controller:

public void startThreadsV4() throws InstantiationException, IllegalAccessException {
    //creating a pool of maxThreads threads
    //ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(maxThreads);
    int m = maxThreads - nThreads;
    if (availableURLs < m) {
        m = availableURLs;
    }
    System.out.println("Starting "+ m + " threads");
    for (int n = 0; n < m; n++) {
        ControllableThread thread = (ControllableThread) threadClass.newInstance();
        thread.setThreadController(this);
        thread.setMessageReceiver(receiver);
        thread.setId(nThreads++);
        thread.setDbhandler(dbhandler);
        thread.setIOhandler(IOhandler);
        thread.setIgnoresundomains(ignoresubdomain);
        thread.start();
        allThreads.add(thread);

    }
}

and here is the thread logic:

public void run() {
    ///first thing is to check if the The thread Controller requested
    IOhandler io = new IOhandler();
    try {
        //Object newTask = dbhandler.getNCURLandMarkTransaction();
        Object newTask = dbhandler.getNCURL();
        System.out.println("new URL -->"+ newTask);

        while (newTask != null) {
            if (tc.getStop() == 1) {
                return;
            } else {
                //treatment in case of ignore sub domains
                if( ignoresundomains == 1 ){
                    String[] temp = new String[2];
                    temp = io.getHostnamefromURL(newTask.toString());
                    if( dbhandler.HostExist(temp[0],temp[1])){
                        return;
                    }
                }
                dbhandler.markURLinprogress(newTask.toString());
                //notify controler of what we do
                mr.receiveMessage(newTask, id);
                //process the new task (URL)
                System.out.println("Processing" + newTask);
                process(newTask, tc.getLastrecord(), tc, dbhandler,IOhandler);
                //dec availabe urls
                tc.decAvailabeURLs();
                dbhandler.markURLcrawled(newTask.toString());
                if (tc.getMaxThreads() > tc.getRunningThreads()) {
                    try {
                        tc.startThreadsV4();
                    } catch (InstantiationException | IllegalAccessException ex) {
                        Logger.getLogger(ControllableThread.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                //System.out.println("DONE");
                //send finished message to controller
                tc.finished(id);
                newTask = dbhandler.getNCURL();
            }
        }
    } catch (SQLException ex) {
        Logger.getLogger(ControllableThread.class.getName()).log(Level.SEVERE, null, ex);
    }

}

Basically what you have to do is: Create a flag for your thread, and set it to false. When do you decided that is the right momento to kill just set your flag to true and call the join() on the thread you want to kill.

This link has the solution better explained. How to properly stop the Thread in Java?

You stop threads in Java by implementing an explicit exit condition (eg. a boolean that can be set from another thread) that is tailored to your business logic. You monitor this boolean in the condition of your while loop and exit from it accordingly. In your particular case I see that you are using the tc.getStop() to achieve something similar. You could move this into the condition of the while loop and && its negation ( !(tc.getStop()) ) together with the other original condition.

There is however no other safe way to simply terminate the threads execution wherever it might be in it's execution flow. Resource leaks can easily arise from that.

For stop thread recommended use Thread.interrupt() method and in code that executed in thread you will check Thread.currentThread().isInterrupted() and if true then exit from loop and therefore stop current thread.

But in you case thread will stop if newTask != null . Or if occur Exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM