您的位置:首页 > 其它

Discuz! X3.2新增管理员无法登录后台的解决办法

2015-03-23 11:30 507 查看
近期接触到流量,由于旧的版本流控不准确,所以相对其改进一下

整体方案:使用jdk1.5的信号量机制,没法送一条消息,信号量加1,当信号量达到上限时,阻塞,等待定时线程来清理(每100毫秒尝试清理一次)

1.首先想到使用Semaphore来实现,不过测试时发现,由于semaphore不能够重入,这导致,在1秒钟内一个线程发送了一条之后,就会阻塞,这样一秒钟每个线程只能发送一条消息。

2.采用ArrayBlockingQueue来实现,每发送一条调用一次put方法(put时如果发现超过1秒钟,则立即清0),定时线程每100毫秒尝试清理一次,但是发现用ArrayBlockingQueue似乎不够轻便,因为其内部维护了一个对象数组。

3.自定义个可重入的信号量类,参照ArrayBlockingQueue来实现,去掉其中的对象数组,值保留put和clear方法,(put方法改名为acquire)。

public class ReentrantSemaphore
{
private int size;
private final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
private int count;

public ReentrantSemaphore(int capacity) {
size = capacity;
lock = new ReentrantLock();
notEmpty = lock.newCondition();
notFull =  lock.newCondition();
}

public void clear() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
count = 0;
notFull.signalAll();
} finally {
lock.unlock();
}
}

public void acquire(int x) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == size)
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
count+=x;
} finally {
lock.unlock();
}
}
}


经过测试,这种方式可以比较好的实现,如果其他人有更好的实现,希望能一起讨论。

完整代码在附件中:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: