我在我的安卓应用程序中有一个名为UploadManager的AsyncTask,它检查处理过的项目,并将它们上传到服务器。
为此,我使用ScheduledExecutorService.scheduleAtFixedRate每隔1分钟检查一次项目,并将它们上传到服务器。
然而,有时会创建多个线程池(这种情况发生的概率为10% ),由于有时相同的请求会被发送两次到服务器,尽管这种并发性是在服务器和客户机级处理的,但我仍然不希望这种情况发生在客户端。
下面是代码的样子。
在MainActivity (start-activity)中,我将UploadManager初始化为:
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这清楚地表明现在有多个线程池,因此,uploadAcknowledgement()方法被多次调用。
在AndroidManifest.xml中,MainActivity声明为:
<application android:label="@string/app_name" android:icon="@drawable/icon">
<activity android:name="MainActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</activity>
.
.发布于 2013-04-17 01:19:19
我最终找出了原因,如果ScheduledExecutor的服务重叠运行,那么它会产生新的工作线程(例如,在本例中,postInformation()创建一个新的工作线程),并最终产生一个新的池。
但是,可以使用newSingleThreadScheduledExecutor而不是newScheduledThreadPool(int corePoolSize)'来避免多个工作进程。
因此,不是将“`scheduledExecutorService”初始化为:
scheduledExecutorService = Executors.newScheduledThreadPool(NUM_OF_THREADS); 它应该被初始化为:
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); 这样可以确保没有多个工作线程在运行。
发布于 2013-04-13 13:48:38
您有一个包含N个文件的列表,并启动了X个线程来上传它,而没有指定哪个线程选择哪个文件。解决此问题的一种方法是将要上载的文件添加到阻塞队列中,并让线程从队列中挑选要上载的文件。这样,任何文件都不会被选中两次。
https://stackoverflow.com/questions/15826661
复制相似问题