ScheduledExecuterService.scheduleAtFixedRate创建多个线程池 - Android

时间:2013-04-05 05:36:28

标签: java android dalvik executorservice scheduledexecutorservice

我的Android应用程序中有一个名为AsyncTask的{​​{1}},用于检查已处理的项目,并将其上传到服务器。
为此,我每隔1分钟使用UploadManager检查项目,然后将其上传到服务器 但是,有时会创建多个线程池(这种情况发生在10%的时间),因此有时会向服务器发送两次相同的请求,尽管这种并发性在服务器和服务器上都得到了处理。客户端,但我仍然不希望这种情况发生在客户端 下面是代码的样子。
在MainActivity(start-activity)中,我将UploadManager启动为:

ScheduledExecutorService.scheduleAtFixedRate

public class MainActivity extends BaseActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); . . . new UploadManager().execute(this); } } 的工作原理如下:

UploadManager

当我检查日志时,它说:

public class UploadManager extends AsyncTask<Context, Integer, Integer> {

    private ScheduledExecutorService scheduledExecutorService;
    private static final int NUM_OF_THREADS = 5;
    private static final int DELAY_IN_SECONDS = 60;
    private Context context;
    private final Logger logger = new Logger(getClass().getSimpleName());

    protected Integer doInBackground(Context... context) {
        this.context = context[0];
        scheduledExecutorService = Executors.newScheduledThreadPool(NUM_OF_THREADS);
        scheduledExecutorService.scheduleAtFixedRate(postInformation, 5, DELAY_IN_SECONDS, TimeUnit.SECONDS);
       return 0;
    }

    private Runnable postInformation = new Runnable() {
        @Override
        public void run() {
            if (NetworkManager.isInternetAvailable(context)) {
                uploadAcknowledgement();
            }
        }
    };

    private void uploadAcknowledgement() {
        List<Acknowledgement> ackList = null;
        try {
            logger.info("RUNNING TASK TO POST ACKNOWLEDGEMENT");
            .
            .
        }
    }
}

这清楚地表明现在有多个线程池,因此,35119 [pool-2-thread-1] INFO Upload Manager - [1363841355530] : 21/03/2013 10:19:15 : RUNNING TASK TO POST ACKNOWLEDGEMENT 35122 [pool-3-thread-1] INFO Upload Manager - [1363841355532] : 21/03/2013 10:19:15 : RUNNING TASK TO POST ACKNOWLEDGEMENT 方法被多次调用。

MainActivity在AndroidManifest.xml中声明为:

uploadAcknowledgement()

2 个答案:

答案 0 :(得分:1)

我最终找出原因,如果ScheduledExecutor的服务运行重叠,那么它会生成新的工作线程(例如,在这种情况下postInformation()创建一个新的工作线程)并最终,新池。
但是,使用newSingleThreadScheduledExecutor代替newScheduledThreadPool(int corePoolSize)'可以避免多名员工 因此,不要将`scheduledExecutorService'初始化为:

scheduledExecutorService = Executors.newScheduledThreadPool(NUM_OF_THREADS);  

它应该被初始化为:

scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();  

这样可以确保没有多个工作线程在运行。

答案 1 :(得分:0)

您有一个N个文件的列表,并启动了X个线程来上传它,而没有指定选择哪个文件的线程。 解决此问题的一种方法是将要上载的文件添加到阻止队列中,让线程选择要从队列上载的文件。这样就不会再挑选两次文件了。