Interview questions: how to stop a running java threads elegant

Thread state transition diagram:

Several easy way to confuse the concept of

Thread.sleep (), Thread.join () or Object.wait (),
they are blocking method statement and throw InterruptedException.
When the thread into the blocked state to call these methods, if the external call interrupt (),
the thread into the ready state, and these methods throw InterruptedException exception.

public void Thread.interrupt() // 设置线程的中断状态flag.
public boolean Thread.isInterrupted() // 获取线程的中断状态flag值
public static boolean Thread.interrupted() // 取线程的中断状态flag值,并重置flag值为false.
public final void join() throws InterruptedException  //指的是调用者进入阻塞状态, 而不是线程对象进入阻塞状态, 线程对象继续在执行, 不受影响, 看下面的例子.
public static void yield(); //线程从运行状态, 回到就绪状态.
//demo: join()
public class BottomBarManager {
    private final Object handlePopupMenuAction(int actionCode, Object... args) {
    switch (actionCode) {
            case Actions.MenuContainer.DOWNLOAD: // 下载
                ThreadTest tt = new ThreadTest();
                tt.start();
                try {
                    tt.join();  //当前线程等待tt线程执行完再往下执行
                    //作用是, 当前的UI线程进入阻塞状态, 直到等tt线程执行完再往下继续执行, tt线程该干什么还干什么, 不受影响.
                    //千万不要误理解成tt线程进入了阻塞状态.
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                JLog.i();
            break;


    }


    private class ThreadTest extends Thread {


        @Override
        public void run() {
            try {
                sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            JLog.i();
        }
    }


}

Best practice is interrupted thread: + interrupt condition variable.

Best template:

public class BestPractice extends Thread {
    private volatile boolean finished = false;   // ① volatile条件变量
    public void stopMe() {
        finished = true;    // ② 发出停止信号
        interrupt();
    }
    @Override
    public void run() {
        while (!finished) {    // ③ 检测条件变量
        try {
                // do dirty work   // ④业务代码
        } catch (InterruptedException e) {
                if (finished) {
                    return;
                }
                continue;
        }
        }
    }
}

④ When the code in the blocking wait () or sleep (), the thread can not immediately detect the condition variable. Thus the code ② at the same time the best call interrupt () method.

Typical is reflected in the volley projects.
// CacheDispatcher.java
public class CacheDispatcher extends Thread {
    private volatile boolean mQuit = false;


    public void quit() {
        mQuit = true;
        interrupt();
    }


    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);


        // Make a blocking call to initialize the cache.
        mCache.initialize();


        while (true) {
            try {
                // Get a request from the cache triage queue, blocking until
                // at least one is available.
                final Request<?> request = mCacheQueue.take(); //****** block方法, it throws InterruptedException;
                request.addMarker("cache-queue-take");


                // Attempt to retrieve this item from cache.
                Cache.Entry entry = mCache.get(request.getCacheKey());
                if (entry == null) {
                    request.addMarker("cache-miss");
                    // Cache miss; send off to the network dispatcher.
                    mNetworkQueue.put(request);
                    continue;
                }


                // We have a cache hit; parse its data for delivery back to the request.
                request.addMarker("cache-hit");
                Response<?> response = null;
                try {
                    response = request.parseNetworkResponse(
                            new NetworkResponse(entry.data, entry.responseHeaders));
                } catch (Exception e) {
                    mDelivery.postError(request, new ParseError(e));
                    continue;
                } catch (Error error) {
                    mDelivery.postError(request, new ParseError(error));
                    continue;
                }
                request.addMarker("cache-hit-parsed");


            } catch (InterruptedException e) {
                // We may have been interrupted because it was time to quit.
                if (mQuit) {
                    return;
                }
                continue;
            } catch (OutOfMemoryError error) {
                if (mQuit) {
                    return;
                }
                continue;
            }
        }
    }


}

In the quit () code, set the condition variable, while calling interrupt () method.

After the write thread class, refer to this template is very elegant and write specifications.

Interrupts are politely requested another thread at a convenient time and it is willing to stop what it is doing.

I like to point a "watching" chant, voice mail, forwarding circle of friends

Published 143 original articles · won praise 607 · views 590 000 +

Guess you like

Origin blog.csdn.net/xcbeyond/article/details/105213026