Sto*_*yan 0 java multithreading synchronization thread-safety
我有一个奇怪的同步架构,我正在寻找一个优雅的解决方案.我已经有了一个解决方案,但我不能说它的有效性,也有点难看.所以这是问题,希望有人可以帮助我.
有两组任务可以启动和运行.每个任务都有自己的线程.这两个组都从一个负责同步部分的超类扩展.为简单起见,我将这两个组称为A组和B组.
条件:
如果只有B组任务在运行,那么它们可以同时运行,并且它们不会相互干扰.
如果启动了组A任务*,则组B任务的构造函数应该失败并出现异常.即使A组任务已在运行,也可以创建任意数量的A组任务
在所有当前的B组任务完成之前,A组任务无法执行.(*从上面)
一次只能运行1个A组任务.他们必须排队.(只要先前的条件仍然适用,可以选择在运行两个A组任务之间阻止B组任务)
我相信我的方法有效但我不喜欢它的工作方式,因为它使用了许多不同的同步点,以及我在等待计数器时有一个睡眠的事实.无论如何,代码如下
public abstract class LockableTask<Params> extends AsyncTask {
private final boolean groupA;
private static Boolean locked = false;
private static final Semaphore semLock = new Semaphore(1);
private static int count = 0;
public LockableTask(boolean groupA) {
this.groupA = groupA;
synchronized (locked) {
if (locked && !groupA) {
throw new InputException("We are locked, please wait");
}
}
}
@Override
protected final AsyncReturn doInBackground(Params... params) {
if (!groupA) {
synchronized (locked) {
count++;
}
}
try {
if (groupA) {
semLock.acquireUninterruptibly();
synchronized (locked) {
locked = true;
}
while (true) {
synchronized (locked) {
if (count == 0) {
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
return runInBackground(params);
} finally {
synchronized (locked) {
if (groupA) {
locked = false;
} else {
count--;
}
}
if (groupA) {
semLock.release();
}
}
}
protected abstract AsyncReturn runInBackground(Params... params);
}
Run Code Online (Sandbox Code Playgroud)
如果有人有一个更好的解决方案,即使只是勉强更好,那将是伟大的
听起来你想要使用ReadWriteLock.让A组的每个任务获得它readLock(),B组的每个任务获得它writeLock().
这样,可以同时运行任意数量的A组任务,但只能运行B组的一个任务(此时不能运行任何其他A组任务).
ReadWriteLock rwLock = getSharedReadWriteLock();
Lock lock = groupA ? rwLock.readLock() : rwLock.writeLock();
lock.lock();
try {
return runInBackground(params);
} finally {
lock.unlock();
}
Run Code Online (Sandbox Code Playgroud)