我想防止Android线程同时在不同线程中运行同一任务。我创建了一个简单的Android应用,该应用使用{
"type": "project",
"license": "proprietary",
"require": {
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/api-pack": "^1.2",
"doctrine/doctrine-migrations-bundle": "^2.1",
"easycorp/easyadmin-bundle": "^2.3",
"lexik/jwt-authentication-bundle": "^2.6",
"nesbot/carbon": "^2.32",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/flex": "^1.3.1",
"symfony/framework-bundle": "4.4.*",
"symfony/security-bundle": "4.4.*",
"symfony/yaml": "4.4.*"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"fzaninotto/faker": "^1.9",
"symfony/maker-bundle": "^1.15",
"symfony/profiler-pack": "^1.0"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "4.4.*"
}
}
}
类读取通知,并回复来自特定程序包的接收到的通知。我使用NotificationsListenerService
为任务(通知)创建多个线程。一切正常,但是同一条消息或通知被放入多个线程中并同时执行,因此我的应用向用户发送了重复的答复,我知道这是由于竞争状况造成的,但是我找不到解决方案对于这个问题。我已经包含了一些代码片段,请让我知道问题出在哪里。
NotificationsListenerService.java
ThreadPoolExecutor
ThreadManager.java
public void onNotificationPosted(final StatusBarNotification sbn) {
if (sbn != null && !sbn.isOngoing() && sbn.getPackageName().equals("com.whatsapp.w4b")) {
notification = sbn.getNotification();
if (notification != null) {
bundle = notification.extras;
remoteInputs = getRemoteInputs(notification);
if (remoteInputs != null && remoteInputs.size() > 0) {
Task task = new Task(getApplicationContext(), notification, bundle, remoteInputs, sbn);
ThreadManager.getManagerInstance().runTask(task);
}
}
}
}
Task.java
public class ThreadManager {
private static final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = NUMBER_OF_CORES * 2;
private static final int MAX_POOL_SIZE = NUMBER_OF_CORES * 2;
private static final int KEEP_ALIVE_TIME = 60;
private static ThreadManager managerInstance = null;
final BlockingQueue<Runnable> WorkQueue;
private final ThreadPoolExecutor threadPoolExecutor;
RejectedMessagesHandler rejectedHandles;
static {
managerInstance = new ThreadManager();
}
private ThreadManager() {
WorkQueue = new LinkedBlockingQueue<Runnable>();
rejectedHandles = new RejectedMessagesHandler();
threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME,
TimeUnit.MILLISECONDS, WorkQueue);
}
public void runTask(Runnable runnable) {
threadPoolExecutor.execute(runnable);
}
public static ThreadManager getManagerInstance() {
return managerInstance;
}
}