简体   繁体   中英

Android Thread is not timing out on wait/notify method

The timeout on b.wait(1000) instruction is not executing after 1 second.
I will appreciate some help on how to execute the timeout on the wait() method.

protected void onCreate(Bundle savedInstanceState) {
    ThreadB b = new ThreadB();
    b.start();

    synchronized (b) {
        try {
            long start = System.currentTimeMillis();
            Log.i(TAG, "Before Wait has started "+start);
            b.wait(1000);
            long finish = System.currentTimeMillis();
            Log.i(TAG, "After Wait has finished "+finish);
        } catch (InterruptedException e) {
            Thread.interrupted();
        }
    }
}

class ThreadB extends Thread {
    @Override
    public void run() {
        synchronized (this) {
            long start = System.currentTimeMillis();
            Log.i(TAG, "*** Thread Start "+start);
            Random ran = new Random();
            for (int i = 0; i < 1E7; i++) {
                Math.sin(ran.nextDouble());
            }

            long finish = System.currentTimeMillis();
            Log.i(TAG, "*** Thread Finish "+finish);
            notify();
        }
    }
}

Your program has a "race" to acquire the lock on the ThreadB object. If the main thread wins the race, the timeout logic works. If the new thread wins, the main thread has to wait for the new thread to finish so that it can grab the lock, and after that then it will call Object.wait and sleep for 1 second.

One quick fix is to make sure that the main thread has the lock before the new thread starts:

ThreadB b = new ThreadB();

synchronized (b) {
    b.start();
    try {
        long start = System.currentTimeMillis();
        ....
    }
}

A better solution is to start using the higher level concepts in the java.util.concurrent library. Instead of creating a new thread, send a task to be computed by a thread pool:

    ExecutorService threadPool = Executors.newFixedThreadPool(1);
    Future<?> submit = threadPool.submit(() -> {
        // ThreadB computation logic
    });

and then specify a timeout to wait for its results:

    try {
        submit.get(1, TimeUnit.SECONDS);
    } catch (Exception e) {
        // handle timeout, interruption, exceptions
    }

Note that on Android, it's not a great idea make the main thread block or wait, even if it's for only 1 second.

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