Java – implementing thread pools in services

I'm trying to implement a service that will perform some work on several parallel threads when requested

My implementation is based on the ThreadPoolExecutor class and linkedblockingqueue

As a basic rule, once all tasks are completed and there are no pending tasks in the queue, I want to stop the service (although the service can be restarted later and follow the same logic)

I have been able to use the following code to achieve the desired results, but I don't know if this method is correct

public class TestService extends Service {
    // Sets the initial threadpool size to 3
    private static final int CORE_POOL_SIZE = 3;

    // Sets the maximum threadpool size to 3
    private static final int MAXIMUM_POOL_SIZE = 3;

    // Sets the amount of time an idle thread will wait for a task before terminating
    private static final int KEEP_ALIVE_TIME = 1;

    // Sets the Time Unit to seconds
    private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

    // A queue of Runnables for the uploading pool
    private final LinkedBlockingQueue<Runnable> uploadQueue = new LinkedBlockingQueue<Runnable>();

    // A managed pool of background upload threads
    private final ThreadPoolExecutor uploadThreadPool = new ThreadPoolExecutor(
            CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE_TIME,KEEP_ALIVE_TIME_UNIT,uploadQueue) {

        @Override
        protected void afterExecute(Runnable r,Throwable t) {
            super.afterExecute(r,t);

            if (getActiveCount() == 1 && getQueue().size() == 0) {
                // we're the last Runnable around + queue is empty,service can be
                // safely stopped.
                TestService.this.stopSelf();
            }
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent,int flags,int startId) {
        // execute a new Runnable
        uploadThreadPool.execute(new TestRunnable());

        /**
         * Indicating that if Android has to kill off this service (i.e. low memory),* it should not restart it once conditions improve.
         */
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        uploadThreadPool.shutdownNow();
        uploadQueue.clear();

        super.onDestroy();
    }
}

So I have something I'm not sure about

>Suppose ondestroy is called, and if my implementation will interrupt all running threads and safely clear pending tasks without interrupting the implementation of ThreadPoolExecutor class, is it safe? The reason I asked is because the queue is associated with the executor, or it may be that shutdown now is asynchronous, depending on the status of the queue Is there a better way? Do I implement this logic internally correctly? In my experience, in some cases, the service is killed (i.e. low memory) and the callback is not called Should I implement similar practices elsewhere? > It is better to declare that the members of my queue executor class are static As @ thetwo said, "once shutdown is called, the executor cannot be reused." The ThreadPoolExecutor class expects a BlockingQueue. What are the advantages and disadvantages of using other types of BlockingQueue implementation (that is, arrayblockingqueue)? As for the way I currently detect that the queue is empty, there are no more pending tasks (especially after the callback) – is this the best practice? Or can I get an indication that the queue is empty and the task is completed in another way?

Appreciate any help!

resolvent

Solution

I think you're trying to implement a service that introduces a lot of problems but doesn't solve them Effectively, you reduce the calling code by one line - create an executable - but eliminate the ability to fine - tune it There is no benefit in scheduling many tasks, because this has been solved by the OS thread scheduler Another malicious caller can break several other programs by adding enough time (true) sleep (100); Cycle

About your question:

>You cannot ensure that all threads are interrupted correctly because threads that do not see the interrupt flag correctly cannot be interrupted For a while (really) except system Cannot interrupt except exit() In theory, you can stop a thread, but for this reason, you can leave the actual task in an incomplete / incomplete state (that is, half open the TCP connection). This feature has been deprecated. > No, you don't realize it correctly For a task that leaves, its queue will simply disappear in the blank, and then once it is closed and called, the executor cannot be reused So you should at least create a new instance of the executor when the service starts. You really should know how to handle the remaining tasks. > No, because 2. > The advantages and disadvantages of list types depend on use cases An ArrayList costs more when growing / shrinking, but it costs less when indexing specific elements (indexof), which is the opposite of a linked list Because your queue is always added to the tail, does not care about any other elements, but the first, and it often grows / shrinks, the linked list is the best choice. > You shouldn't do this because the execution order of threads is undefined In the worst case, your calling program is interrupted every time until the service is completed, which will cause the service to start and stop continuously without special reason, and waste a lot of processing time Why do you even want to stop the service? If it doesn't matter, it won't do anything except use a few bytes of memory

The above is the whole content of Java - implementing thread pool in services collected and sorted out by programming house for you. I hope this article can help you solve the program development problems encountered by Java - implementing thread pool in services.

If you think the content of the programming home website is good, you are welcome to recommend the programming home website to programmers and friends.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>